FIELD NOTE 002TypeScriptReviewed July 2026

Deep Clone (Object/Array/Date/RegExp Support)

Solves reference type shallow copy issues, supports deep cloning of primitive types, objects, arrays, dates, and regular expressions to avoid affecting original data when modifying copies

Copy the complete example or adapt its typed interface to your project. Comments are kept inside the snippet so the intent travels with the code.

pattern.ts
/**
 * Deep clone function
 * @param target Value to be cloned
 * @returns New cloned value
 */
function deepClone<T>(target: T): T {
  // Return primitive types directly
  if (target === null || typeof target !== 'object') return target;

  // Handle Date objects
  if (target instanceof Date) return new Date(target.getTime()) as T;
  // Handle RegExp objects
  if (target instanceof RegExp) return new RegExp(target.source, target.flags) as T;

  // Handle arrays/objects
  const cloneTarget = Array.isArray(target) ? [] : {} as T;
  for (const key in target) {
    if (Object.prototype.hasOwnProperty.call(target, key)) {
      cloneTarget[key] = deepClone(target[key]);
    }
  }
  return cloneTarget;
}

// Usage Example
const original = { a: 1, b: { c: 2 }, d: [3, 4], e: new Date() };
const copy = deepClone(original);
copy.b.c = 100;
console.log(original.b.c); // 2 (original data remains unchanged)

Perfect for state management, form data duplication, and complex data processing requiring complete reference isolation

Implementation note

Review the input assumptions and browser or runtime support before adopting a utility unchanged. Small helpers are easiest to maintain when their contract stays narrow.

How it works

The function returns primitives unchanged, creates new Date and RegExp instances, then recursively copies owned enumerable properties into a fresh array or object. Each nested reference is visited so ordinary edits to the clone do not reach the source.

What to watch for

This implementation does not preserve prototypes, property descriptors, symbols, maps, sets, typed arrays, circular references, or shared-reference identity. Deep cloning large graphs is also expensive and can hide a state-design problem rather than solve it.

Production use

Use it only for the explicitly supported data shapes, such as a small form draft with arrays, plain objects, dates, and regular expressions. Prefer structuredClone when its supported types and runtime availability match the project requirements.

Before you ship

  • Confirm the input contract with tests that cover empty, invalid, boundary, and representative real-world values before sharing the helper across a codebase.
  • Keep the function focused on one responsibility and name any project-specific policy explicitly instead of hiding it inside a generic-looking utility.
  • Measure behavior in the browsers or runtime versions your product supports, especially when timing, storage, DOM state, locale, or network access is involved.
  • Document the return type, mutation behavior, failure mode, and performance characteristics beside the call site so future maintainers can evaluate changes safely.
  • Compare the example with current official platform documentation when it relies on a browser API, language feature, or runtime behavior that may change over time.
  • If the helper crosses a trust boundary, validate again on the server and avoid treating browser-side checks, TypeScript annotations, or formatted output as a security guarantee.
  • Add a small regression test whenever a real edge case is discovered; concrete examples preserve the reason behind a guard more reliably than a general comment.