Created
April 4, 2023 12:10
-
-
Save vikiboss/4f2f9571b7233204ef5f96e4ba73e78c to your computer and use it in GitHub Desktop.
Deep Clone for TS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function isObject(obj: unknown): obj is Record<string, unknown> { | |
return typeof obj === 'object' && obj !== null | |
} | |
export function deepClone<T>(obj: T, cache: Map<unknown, unknown> = new Map()): T { | |
if (obj === null || typeof obj !== 'object') { | |
return obj | |
} | |
if (cache.has(obj)) { | |
return cache.get(obj) as T | |
} | |
let result: unknown | |
if (obj instanceof Date) { | |
result = new Date(obj.getTime()) | |
} else if (obj instanceof Buffer) { | |
result = Buffer.from(obj) | |
} else if (ArrayBuffer.isView(obj) && obj.buffer instanceof ArrayBuffer) { | |
result = (obj as unknown as ArrayBuffer).slice(0) | |
} else if (obj instanceof Map) { | |
const resultMap = new Map() | |
cache.set(obj, resultMap) | |
for (const [key, value] of obj.entries()) { | |
resultMap.set(deepClone(key, cache), deepClone(value, cache)) | |
} | |
result = resultMap | |
} else if (obj instanceof Set) { | |
const resultSet = new Set() | |
cache.set(obj, resultSet) | |
for (const value of obj.values()) { | |
resultSet.add(deepClone(value, cache)) | |
} | |
result = resultSet | |
} else if (typeof obj === 'function') { | |
result = obj | |
} else if (isObject(obj)) { | |
const newObj: Record<string, unknown> = {} | |
cache.set(obj, newObj) | |
Object.keys(obj).forEach(key => { | |
newObj[key] = deepClone(obj[key], cache) | |
}) | |
result = newObj | |
} else { | |
result = obj | |
} | |
return result as T | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment