Skip to content

Instantly share code, notes, and snippets.

@Meettya
Created August 5, 2024 08:19
Show Gist options
  • Save Meettya/dc301703dca785c7df4a95787d922f96 to your computer and use it in GitHub Desktop.
Save Meettya/dc301703dca785c7df4a95787d922f96 to your computer and use it in GitHub Desktop.
extend TS
export const extend = (deep: boolean, target: any, ...args: any[]): any => {
if (!_isClass(deep, 'Boolean')) {
args.unshift(target);
[target, deep] = [deep || {}, false];
}
// Handle case when target is a string or something (possible in deep copy)
target = _isPrimitiveType(target) ? {} : target;
for (const options of args) {
if (options) {
for (const [name, copy] of Object.entries(options)) {
target[name] = _findValue(deep, copy, target[name]);
}
}
}
return target;
};
// Internal methods from now
const _isClass = (obj: any, str: string): boolean => {
return Object.prototype.toString.call(obj) === `[object ${str}]`;
};
const _isOwnProp = (obj: any, prop: string): boolean => {
return Object.prototype.hasOwnProperty.call(obj, prop);
};
const _isTypeOf = (obj: any, str: string): boolean => {
return str === typeof obj;
};
const _isPlainObj = (obj: any): boolean => {
if (!obj) return false;
if (obj.nodeType || obj.setInterval || !_isClass(obj, 'Object')) return false;
// Not own constructor property must be Object
if (obj.constructor &&
!_isOwnProp(obj, 'constructor') &&
!_isOwnProp(obj.constructor.prototype, 'isPrototypeOf')) {
return false;
}
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
for (const key in obj) {
if (key === undefined || !_isOwnProp(obj, key)) {
return false;
}
}
return true;
};
const _isPrimitiveType = (obj: any): boolean => {
return !(_isTypeOf(obj, 'object') || _isTypeOf(obj, 'function'));
};
const _prepareClone = (copy: any, src: any): any => {
if (_isClass(copy, 'Array')) {
return _isClass(src, 'Array') ? src : [];
} else {
return _isPlainObj(src) ? src : {};
}
};
const _findValue = (deep: boolean, copy: any, src: any): any => {
// if we're merging plain objects or arrays
if (deep && (_isClass(copy, 'Array') || _isPlainObj(copy))) {
const clone = _prepareClone(copy, src);
return extend(deep, clone, copy);
} else {
return copy;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment