@@ -68,7 +68,10 @@ export function objectEntries<T extends object>(obj: T) {
6868}
6969
7070/**
71- * Deep merge :P
71+ * Deep merge
72+ *
73+ * The first argument is the target object, the rest are the sources.
74+ * The target object will be mutated and returned.
7275 *
7376 * @category Object
7477 */
@@ -105,6 +108,62 @@ export function deepMerge<T extends object = object, S extends object = T>(targe
105108 return deepMerge ( target , ...sources )
106109}
107110
111+ /**
112+ * Deep merge
113+ *
114+ * Differs from `deepMerge` in that it merges arrays instead of overriding them.
115+ *
116+ * The first argument is the target object, the rest are the sources.
117+ * The target object will be mutated and returned.
118+ *
119+ * @category Object
120+ */
121+ export function deepMergeWithArray < T extends object = object , S extends object = T > ( target : T , ...sources : S [ ] ) : DeepMerge < T , S > {
122+ if ( ! sources . length )
123+ return target as any
124+
125+ const source = sources . shift ( )
126+ if ( source === undefined )
127+ return target as any
128+
129+ if ( Array . isArray ( target ) && Array . isArray ( source ) )
130+ target . push ( ...source )
131+
132+ if ( isMergableObject ( target ) && isMergableObject ( source ) ) {
133+ objectKeys ( source ) . forEach ( ( key ) => {
134+ if ( key === '__proto__' || key === 'constructor' || key === 'prototype' )
135+ return
136+
137+ // @ts -expect-error
138+ if ( Array . isArray ( source [ key ] ) ) {
139+ // @ts -expect-error
140+ if ( ! target [ key ] )
141+ // @ts -expect-error
142+ target [ key ] = [ ]
143+
144+ // @ts -expect-error
145+ deepMergeWithArray ( target [ key ] , source [ key ] )
146+ }
147+ // @ts -expect-error
148+ else if ( isMergableObject ( source [ key ] ) ) {
149+ // @ts -expect-error
150+ if ( ! target [ key ] )
151+ // @ts -expect-error
152+ target [ key ] = { }
153+
154+ // @ts -expect-error
155+ deepMergeWithArray ( target [ key ] , source [ key ] )
156+ }
157+ else {
158+ // @ts -expect-error
159+ target [ key ] = source [ key ]
160+ }
161+ } )
162+ }
163+
164+ return deepMergeWithArray ( target , ...sources )
165+ }
166+
108167function isMergableObject ( item : any ) : item is Object {
109168 return isObject ( item ) && ! Array . isArray ( item )
110169}
0 commit comments