Skip to content

Instantly share code, notes, and snippets.

@mir4ef
Created January 9, 2018 03:14
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mir4ef/c172583bdb968951d9e57fb50d44c3f7 to your computer and use it in GitHub Desktop.
Save mir4ef/c172583bdb968951d9e57fb50d44c3f7 to your computer and use it in GitHub Desktop.
Deep merging of JavaScript objects (in TypeScript)
interface IIsObject {
(item: any): boolean;
}
interface IObject {
[key: string]: any;
}
interface IDeepMerge {
(target: IObject, ...sources: Array<IObject>): IObject;
}
/**
* @description Method to check if an item is an object. Date and Function are considered
* an object, so if you need to exclude those, please update the method accordingly.
* @param item - The item that needs to be checked
* @return {Boolean} Whether or not @item is an object
*/
export const isObject: IIsObject = (item: any): boolean => {
return (item === Object(item) && !Array.isArray(item));
};
/**
* @description Method to perform a deep merge of objects
* @param {Object} target - The targeted object that needs to be merged with the supplied @sources
* @param {Array<Object>} sources - The source(s) that will be used to update the @target object
* @return {Object} The final merged object
*/
export const deepMerge: IDeepMerge = (target: IObject, ...sources: Array<IObject>): IObject => {
// return the target if no sources passed
if (!sources.length) {
return target;
}
const result: IObject = target;
if (isObject(result)) {
const len: number = sources.length;
for (let i = 0; i < len; i += 1) {
const elm: any = sources[i];
if (isObject(elm)) {
for (const key in elm) {
if (elm.hasOwnProperty(key)) {
if (isObject(elm[key])) {
if (!result[key] || !isObject(result[key])) {
result[key] = {};
}
deepMerge(result[key], elm[key]);
} else {
if (Array.isArray(result[key]) && Array.isArray(elm[key])) {
// concatenate the two arrays and remove any duplicate primitive values
result[key] = Array.from(new Set(result[key].concat(elm[key])));
} else {
result[key] = elm[key];
}
}
}
}
}
}
}
return result;
};
@diegoarcega
Copy link

thanks, the return of deepMerge should be a combination of the passed objects, not IObject, TS complains otherwise

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment