avatar

Le Do Nghiem

Software Engineer

  • About me
  • Books
  • Snippets
  • Blog

© 2026 Le Do Nghiem. All rights reserved.

Contact |

Back to Snippets

deepClone Function

Create a deep copy of objects and arrays, avoiding reference issues.

LanguageTypeScript
Last UpdatedDec 21, 2025
deep-clone.ts
export function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (obj instanceof Date) {
    return new Date(obj.getTime()) as unknown as T;
  }

  if (obj instanceof Array) {
    return obj.map(item => deepClone(item)) as unknown as T;
  }

  if (typeof obj === 'object') {
    const clonedObj = {} as T;
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key]);
      }
    }
    return clonedObj;
  }

  return obj;
}

Creating deep copies of objects is essential when you need to modify data without affecting the original. This utility handles nested objects and arrays.

export function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (obj instanceof Date) {
    return new Date(obj.getTime()) as unknown as T;
  }

  if (obj instanceof Array) {
    return obj.map(item => deepClone(item)) as unknown as T;
  }

  if (typeof obj === 'object') {
    const clonedObj = {} as T;
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key]);
      }
    }
    return clonedObj;
  }

  return obj;
}

How It Works

  • Handles primitives by returning them directly.
  • Creates new Date instances for Date objects.
  • Recursively clones arrays and objects.
  • Preserves the structure of nested data.

Example Usage

const original = {
  name: 'John',
  address: {
    city: 'New York',
    zip: '10001',
  },
  hobbies: ['reading', 'coding'],
};

const cloned = deepClone(original);
cloned.address.city = 'Boston'; // Doesn't affect original
cloned.hobbies.push('gaming'); // Doesn't affect original

console.log(original.address.city); // "New York"
console.log(original.hobbies); // ["reading", "coding"]

Alternative: JSON Method

For simple cases (no functions, Dates, or undefined), you can use:

export function simpleDeepClone<T>(obj: T): T {
  return JSON.parse(JSON.stringify(obj));
}

Limitations:

  • Doesn't handle functions
  • Loses Date objects (becomes strings)
  • Doesn't preserve undefined values
  • Can't clone circular references

Use Cases

  • Creating editable copies of form data
  • Undo/redo functionality
  • Immutable state updates
  • Preventing accidental mutations
  • Cloning configuration objects

Notes

  • The recursive version handles most cases but may fail with circular references.
  • For production use, consider libraries like lodash.cloneDeep or structuredClone (modern browsers).
  • structuredClone is a native browser API that handles more edge cases.

A reliable utility for creating independent copies of complex data structures.

Previous Snippet

formatDate Function