Skip to content

Instantly share code, notes, and snippets.

@erikvullings
Last active September 3, 2024 09:02
Show Gist options
  • Save erikvullings/ada7af09925082cbb89f40ed962d475e to your computer and use it in GitHub Desktop.
Save erikvullings/ada7af09925082cbb89f40ed962d475e to your computer and use it in GitHub Desktop.
Deep copy or clone in TypeScript
/**
* Deep copy function for TypeScript.
* @param T Generic type of target/copied value.
* @param target Target value to be copied.
* @see Source project, ts-deepcopy https://github.com/ykdr2017/ts-deepcopy
* @see Code pen https://codepen.io/erikvullings/pen/ejyBYg
*/
export const deepCopy = <T>(target: T): T => {
if (target === null) {
return target;
}
if (target instanceof Date) {
return new Date(target.getTime()) as any;
}
if (target instanceof Array) {
const cp = [] as any[];
(target as any[]).forEach((v) => { cp.push(v); });
return cp.map((n: any) => deepCopy<any>(n)) as any;
}
if (typeof target === 'object' && target !== {}) {
const cp = { ...(target as { [key: string]: any }) } as { [key: string]: any };
Object.keys(cp).forEach(k => {
cp[k] = deepCopy<any>(cp[k]);
});
return cp as T;
}
return target;
};
@dominikbrazdil
Copy link

I faced an issue when cloning object which had empty objects inside - the empty objects were only passed by reference and therefore any change to the new object affected the old one. I removed the 'target !== {}' to make it work for me. @erikvullings was there any other reason except from optimization for having the condition there?

@erikvullings
Copy link
Author

This working with array, objects and persist datatype

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

True, but it is a rather expensive operation, and it will fail on circular objects, i.e. objects referring to itself.

@erikvullings
Copy link
Author

I faced an issue when cloning object which had empty objects inside - the empty objects were only passed by reference and therefore any change to the new object affected the old one. I removed the 'target !== {}' to make it work for me. @erikvullings was there any other reason except from optimization for having the condition there?

No, not really - this copy/clone function is for basic usage only. I've also ported it to a more elaborate version that takes care of several other issues too, deep-copy-ts. Or you can get it from npm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment