@@ -66,10 +66,25 @@ function createEmpty<T>(source: T) {
6666
6767const keys = typeof Reflect === 'undefined' ? Object . keys : Reflect . ownKeys ;
6868
69+ // ================================ Merge ================================
70+ export type MergeFn = ( current : any , next : any ) => any ;
71+
6972/**
70- * Merge objects which will create
73+ * Merge multiple objects. Support custom merge logic.
74+ * @param sources object sources
75+ * @param config.prepareArray Customize array prepare function.
76+ * It will return empty [] by default.
77+ * So when match array, it will auto be override with next array in sources.
7178 */
72- export function merge < T extends object > ( ...sources : T [ ] ) {
79+ export function mergeWith < T extends object > (
80+ sources : T [ ] ,
81+ config : {
82+ prepareArray ?: MergeFn ;
83+ } = { } ,
84+ ) {
85+ const { prepareArray } = config ;
86+ const finalPrepareArray : MergeFn = prepareArray || ( ( ) => [ ] ) ;
87+
7388 let clone = createEmpty ( sources [ 0 ] ) ;
7489
7590 sources . forEach ( src => {
@@ -89,7 +104,7 @@ export function merge<T extends object>(...sources: T[]) {
89104
90105 if ( isArr ) {
91106 // Array will always be override
92- clone = set ( clone , path , [ ] ) ;
107+ clone = set ( clone , path , finalPrepareArray ( originValue , value ) ) ;
93108 } else if ( ! originValue || typeof originValue !== 'object' ) {
94109 // Init container if not exist
95110 clone = set ( clone , path , createEmpty ( value ) ) ;
@@ -109,3 +124,11 @@ export function merge<T extends object>(...sources: T[]) {
109124
110125 return clone ;
111126}
127+
128+ /**
129+ * Merge multiple objects into a new single object.
130+ * Arrays will be replaced by default.
131+ */
132+ export function merge < T extends object > ( ...sources : T [ ] ) {
133+ return mergeWith ( sources ) ;
134+ }
0 commit comments