Created
April 5, 2024 19:16
-
-
Save nicothin/12a9242a2948988187ff2fc25a5cacfb to your computer and use it in GitHub Desktop.
merge Objects Recursively
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import isEqual from 'lodash.isequal'; | |
type AnyObj = Record<string, any>; | |
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void | |
? I | |
: never; | |
export const mergeObjectsRecursively = <T extends AnyObj, U extends AnyObj[]>( | |
...objects: [T, ...U] | |
): T & UnionToIntersection<U[number]> => { | |
const result = {} as T & UnionToIntersection<U[number]>; | |
objects.forEach((obj) => { | |
Object.entries(obj).forEach(([key, value]) => { | |
if (Array.isArray(value) && Array.isArray(result[key])) { | |
const uniqueElements = value.filter( | |
(element) => !result[key].some((item: any) => isEqual(item, element)) | |
); | |
(result[key] as any) = [...result[key], ...uniqueElements]; | |
} else if ( | |
typeof value === 'object' && | |
value !== null && | |
typeof result[key] === 'object' && | |
result[key] !== null | |
) { | |
(result[key] as AnyObj) = mergeObjectsRecursively(result[key], value); | |
} else { | |
(result[key] as any) = value; | |
} | |
}); | |
}); | |
return result; | |
}; | |
const obj1 = { | |
imya: 'John', | |
age: 30, | |
foo: { | |
bar: 'bащщщщщaz', | |
}, | |
arr: [1, 2, 3], | |
action: { | |
first111: () => console.log('111', 111) | |
}, | |
hobbies: ['coding', 'reading', 'swimming', { foo: 'bar' }], | |
}; | |
const obj2 = { | |
age: 31, | |
cool: false, | |
foo: { | |
bar: 'baz', | |
baz: 'bar', | |
}, | |
arr: [3, 4], | |
hobbies: ['coding', 'hiking', { foo: 'bar' }], | |
}; | |
const obj3 = { | |
cool: true, | |
action: { | |
first111: () => console.log('1', 1), | |
first222: () => console.log('222', 222) | |
}, | |
}; | |
const mergedObj = mergeObjectsRecursively(obj1, obj2, obj3); | |
console.log('>>> mergedObj', mergedObj); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment