Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

deepClone

Deep clones an object using JSON serialization. Note: Does not preserve functions, symbols, undefined, Date, Map, Set, etc.

TypeScript
Copied!
1/**
2 * Deep clones an object using JSON serialization.
3 * Note: Does not preserve functions, symbols, undefined, Date, Map, Set, etc.
4 *
5 * @param obj - The input object to clone.
6 * @returns A deep copy of the input object.
7 */
8export function deepClone<T>(obj: T): T {
9  return JSON.parse(JSON.stringify(obj));
10}
  • Simple and Readable

    Uses a well-known JSON.stringify + JSON.parse pattern, making the intent clear and understandable at a glance.

  • Performs a Deep Copy

    Recursively copies nested objects and arrays, avoiding references to the original structure.

  • Fast for JSON-Compatible Data

    Highly performant for plain data structures that don't include special types like functions or Dates.

  • Stateless and Pure

    Produces a clean, immutable clone without side effects or shared references.

Tests | Examples

TypeScript
Copied!
1test('deepClone - clones nested objects correctly', () => {
2  const original = { a: 1, b: { c: 2 } };
3  const clone = deepClone(original);
4
5  expect(clone).toEqual(original);
6  expect(clone).not.toBe(original);
7  expect(clone.b).not.toBe(original.b);
8});
9
10test('deepClone - clones arrays correctly', () => {
11  const original = [1, [2, 3], { a: 4 }];
12  const clone = deepClone(original);
13
14  expect(clone).toEqual(original);
15  expect(clone).not.toBe(original);
16  expect(clone[1]).not.toBe(original[1]);
17  expect(clone[2]).not.toBe(original[2]);
18});
19
20test('deepClone - ignores non-serializable properties', () => {
21  const original = {
22    a: 1,
23    b: undefined,
24    c: () => 42,
25    d: Symbol('x'),
26    e: new Date(),
27  };
28  const clone = deepClone(original);
29
30  expect(clone).toEqual({ a: 1 }); // only a survives
31});
32
33test('deepClone - works with null and primitives', () => {
34  expect(deepClone(null)).toBeNull();
35  expect(deepClone(42)).toBe(42);
36  expect(deepClone('test')).toBe('test');
37  expect(deepClone(true)).toBe(true);
38});

Common Use Cases

  • Immutability in State Management

    Create independent deep copies of state objects in libraries like Redux or MobX.

  • Resetting Data

    Clone initial values to reset forms, configs, or game state without affecting originals.

  • Serialization-Safe Data Transfer

    Clone and prepare plain objects for sending via APIs, localStorage, or message passing.

  • Testing and Mocking

    Clone test data to ensure modifications in one test don’t affect others.

  • Snapshotting and Undo History

    Store full copies of objects at various points in time to support undo/redo or diffing.

Codebase: Utilities -> Objects -> deepClone | Yevhen Klymentiev