apollo-utilities
Version:
Utilities for working with GraphQL ASTs
38 lines (33 loc) • 1.02 kB
text/typescript
const { toString } = Object.prototype;
/**
* Deeply clones a value to create a new instance.
*/
export function cloneDeep<T>(value: T): T {
return cloneDeepHelper(value, new Map());
}
function cloneDeepHelper<T>(val: T, seen: Map<any, any>): T {
switch (toString.call(val)) {
case "[object Array]": {
if (seen.has(val)) return seen.get(val);
const copy: T & any[] = (val as any).slice(0);
seen.set(val, copy);
copy.forEach(function (child, i) {
copy[i] = cloneDeepHelper(child, seen);
});
return copy;
}
case "[object Object]": {
if (seen.has(val)) return seen.get(val);
// High fidelity polyfills of Object.create and Object.getPrototypeOf are
// possible in all JS environments, so we will assume they exist/work.
const copy = Object.create(Object.getPrototypeOf(val));
seen.set(val, copy);
Object.keys(val).forEach(key => {
copy[key] = cloneDeepHelper((val as any)[key], seen);
});
return copy;
}
default:
return val;
}
}