Deep merging of JS objects (in TypeScript)
Fri Oct 23 2020 10:25:06 GMT+0000 (Coordinated Universal Time)
Saved by
@kjetilhp
#javascript
#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;
};
content_copyCOPY
https://gist.github.com/mir4ef/c172583bdb968951d9e57fb50d44c3f7
Comments