@@ -1622,15 +1622,26 @@ export function deepEqual(obj1: any, obj2: any): boolean {
16221622 return true ;
16231623}
16241624
1625+ /**
1626+ * Checks if a value is a plain object (not an array, null, or other type).
1627+ *
1628+ * @param value - The value to check
1629+ * @returns True if the value is a plain object, false otherwise
1630+ */
1631+ export function isPlainObject ( value : any ) : value is Record < string , any > {
1632+ return ! ! value && typeof value === "object" && ! Array . isArray ( value ) ;
1633+ }
1634+
16251635/**
16261636 * Deeply merges the source object into the target object.
16271637 *
16281638 * @param target - The target object to merge into
16291639 * @param source - The source object to merge from
1630- * @returns void
1640+ * @returns boolean indicating whether changes were made
16311641 */
1632- export function deepMerge ( target : any , source : any ) : void {
1642+ export function deepMerge ( target : any , source : any ) : boolean {
16331643 const hasOwn = Object . prototype . hasOwnProperty ;
1644+ let hasChanges = false ;
16341645
16351646 for ( const key in source as any ) {
16361647 if ( ! hasOwn . call ( source , key ) ) {
@@ -1649,12 +1660,12 @@ export function deepMerge(target: any, source: any): void {
16491660 continue ;
16501661 }
16511662
1652- const isSourceArray = Array . isArray ( sourceValue ) ;
1663+ hasChanges = true ;
16531664
1654- if ( isSourceArray ) {
1665+ if ( Array . isArray ( sourceValue ) ) {
16551666 const isTargetArray = Array . isArray ( targetValue ) ;
16561667 const clonedItems = sourceValue . map ( ( item : unknown ) =>
1657- item && typeof item === "object" ? { ...item } : item
1668+ isPlainObject ( item ) ? { ...item } : item
16581669 ) ;
16591670
16601671 if ( isTargetArray ) {
@@ -1667,19 +1678,24 @@ export function deepMerge(target: any, source: any): void {
16671678 continue ;
16681679 }
16691680
1670- if ( sourceValue && typeof sourceValue === "object" ) {
1671- if (
1672- ! targetValue ||
1673- typeof targetValue !== "object" ||
1674- Array . isArray ( targetValue )
1675- ) {
1676- target [ key ] = { } ;
1681+ if ( isPlainObject ( sourceValue ) ) {
1682+ const targetIsObject = isPlainObject ( targetValue ) ;
1683+ const nextTarget = targetIsObject ? { ...targetValue } : { } ;
1684+ const nestedChanged = deepMerge ( nextTarget , sourceValue ) ;
1685+
1686+ if ( ! targetIsObject ) {
1687+ target [ key ] = nextTarget ;
1688+ continue ;
16771689 }
16781690
1679- deepMerge ( target [ key ] , sourceValue ) ;
1691+ if ( nestedChanged ) {
1692+ target [ key ] = nextTarget ;
1693+ }
16801694 continue ;
16811695 }
16821696
16831697 target [ key ] = sourceValue ;
16841698 }
1699+
1700+ return hasChanges ;
16851701}
0 commit comments