Created
May 29, 2023 21:27
-
-
Save Juknum/98013c1224064e6228391f1af5fd655c to your computer and use it in GitHub Desktop.
Prototypes extension to the Object interface
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
export {}; | |
declare global { | |
interface Object { | |
/** | |
* Deep merge two or more objects into the first one | |
* @param {object} target The object to merge into | |
* @param {...object} sources The objects to merge into the target | |
* | |
* @example Object.merge({ a: 1, b: 2 }, { b: 3, c: 4 }) // { a: 1, b: 3, c: 4 } | |
* @example Object.merge({ a: 1, b: { c: 2, d: 3 } }, { b: { d: 4, e: 5 } }) // { a: 1, b: { c: 2, d: 4, e: 5 } } | |
*/ | |
merge<T>(target: T, ...sources: Array<Partial<T & Record<string, unknown>>>): T & Record<string, unknown>; | |
/** | |
* Check if the given item is a JS Object | |
* @param {unknown} item to be tested | |
* @returns {boolean} true if the item is a JS Object | |
* | |
* @example Object.isObject({}) // true | |
* @example Object.isObject({ a: 1 }) // true | |
* @example Object.isObject({ a: 1, b: {} }) // true | |
* @example Object.isObject([]) // false | |
*/ | |
isObject(item: unknown): boolean; | |
} | |
} | |
if (!Object.prototype.isObject) { | |
Object.defineProperty(Object.prototype, 'isObject', { | |
value: (item: unknown): boolean => { | |
return item !== undefined && item !== null && typeof item === 'object' && !Array.isArray(item); | |
}, | |
configurable: true, | |
writable: true, | |
}); | |
} | |
if (!Object.prototype.merge) { | |
Object.defineProperty(Object.prototype, 'merge', { | |
value: (target: object, ...sources: object[]) => { | |
if (!sources.length) return target; | |
const source: Record<string, unknown> = sources.shift() as Record<string, unknown>; | |
if (Object.isObject(target) && Object.isObject(source)) { | |
for (const key in source) { | |
if (Object.isObject(source[key])) { | |
if (!(target as Record<string, object>)[key]) Object.assign(target, { [key]: {} }); | |
Object.merge((target as Record<string, object>)[key], source[key] as object); | |
} else Object.assign(target, { [key]: source[key] }); | |
} | |
} | |
return Object.merge(target, ...sources); | |
}, | |
configurable: true, | |
writable: true, | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment