Skip to content

Instantly share code, notes, and snippets.

@nicothin
Created April 5, 2024 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicothin/12a9242a2948988187ff2fc25a5cacfb to your computer and use it in GitHub Desktop.
Save nicothin/12a9242a2948988187ff2fc25a5cacfb to your computer and use it in GitHub Desktop.
merge Objects Recursively
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