Implement deepClone(value) — return a new value that has the same structure as the input but shares no references with it. Mutating the clone (or anything nested inside it) must never reach back and touch the original. This is the function structuredClone gives you for free in modern runtimes, but the point of the exercise is to build it yourself: handle nested objects and arrays, detect cycles, and decide what to do about types that don't survive a JSON round-trip.
// Returns a deep, structural copy of `value`. The result shares no object
// references with the input — mutating the result never mutates the input.
function deepClone<T>(value: T): T;
const original = { name: 'Ada', address: { city: 'London' } };
const copy = deepClone(original);
copy.address.city = 'Paris';
original.address.city; // 'London' — original is untouched
copy === original; // false — top-level reference is new
copy.address === original.address; // false — nested reference is new
// Arrays clone recursively.
const arr = [[1, 2], [3, 4]];
const cloned = deepClone(arr);
cloned[0].push(99);
arr[0]; // [1, 2] — original inner array is untouched
// Cycles are handled — no stack overflow.
const a = { name: 'a' };
a.self = a; // a points at itself
const b = deepClone(a);
b.self === b; // true — cycle is preserved, but to the *clone*
b.self === a; // false — never references the original
// Primitives come back verbatim.
deepClone(42); // 42
deepClone('hello'); // 'hello'
deepClone(null); // null
deepClone(undefined); // undefined
WeakMap keyed by seen source object to map each original to its clone.Array.isArray(value) distinguishes the two — they need different containers ([] vs {}) but the same recursive treatment.Object.keys — don't copy the prototype chain, don't copy inherited properties.null is its own thing. typeof null === 'object' but null has no properties. Return it verbatim, not {}.JSON.parse(JSON.stringify(...)). It looks tempting but silently drops undefined, turns Date into a string, throws on cycles, and erases functions and Symbols. See the solution's "Going further" for what a fuller implementation would add.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.