Created
August 5, 2024 08:19
-
-
Save Meettya/dc301703dca785c7df4a95787d922f96 to your computer and use it in GitHub Desktop.
extend TS
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 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