@@ -68,7 +68,10 @@ export function objectEntries<T extends object>(obj: T) {
68
68
}
69
69
70
70
/**
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.
72
75
*
73
76
* @category Object
74
77
*/
@@ -105,6 +108,62 @@ export function deepMerge<T extends object = object, S extends object = T>(targe
105
108
return deepMerge ( target , ...sources )
106
109
}
107
110
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
+
108
167
function isMergableObject ( item : any ) : item is Object {
109
168
return isObject ( item ) && ! Array . isArray ( item )
110
169
}
0 commit comments