How to Deep Clone an Object & Preserve its Type with TypeScript ?
Last Updated :
01 Aug, 2024
In TypeScript, deep cloning an object by preserving its type consists of retaining the same structure and type information as of original object.
Below are the approaches to Deep Clone an Object & Preserve its Type:
Using JSON.stringify and JSON.parse
In this approach, we are using the JSON.stringify and JSON.parse functions to perform a deep clone of the object. The DeepClone<T> type makes sure that the original object type structure is preserved during the cloning process, which is checked using instanceOf, and the boolean value is stored and printed from (preserveRes) variable.
Syntax:
JSON.stringify(value, replacer, space);
JSON.parse( string, function )
Example: The below example uses JSON.stringify and JSON.parse to deep-clone an object and preserve its type with TypeScript.
JavaScript
type DeepClone<T> = T extends object ? {
[K in keyof T]: DeepClone<T[K]> } : T;
function approach1Fn<T>(obj: T): DeepClone<T> {
return JSON.parse(JSON.stringify(obj));
}
interface Person {
name: string;
age: number;
}
const person: Person = { name: 'GeeksforGeeks', age: 23 };
const res = approach1Fn(person);
console.log(res);
const preserveRes: boolean = res instanceof Object;
console.log('Type is preserved:', preserveRes);
Output:
{ name: 'GeeksforGeeks', age: 23 }
Type is preserved: true
Using Object.Assign function
In this approach, we are using the Object.assign() function for deep cloning by recursively traversing object properties and creating a new object. Type preservation is preserved through a subsequent type assertion (as T), as verified by checking the cloned result's instance of an object (preserveRes instanceof Object).
Syntax:
Object.assign(target, ...sources);
Example: The below example uses Object.assign function to Deep Clone an Object and Preserve its Type with TypeScript.
JavaScript
function approach2Fn<T>(obj: T): T {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
const res: any = Array
.isArray(obj) ? [] : {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
res[key] = approach2Fn(obj[key]);
}
}
return Object.assign(res, obj) as T;
}
interface Person {
name: string;
website: string;
}
const per: Person =
{
name: 'GeeksforGeeks',
website: 'www.geeksforgeeks.org'
};
const res = approach2Fn(per);
console.log(res);
const preserveRes: boolean = res instanceof Object;
console.log('Type is preserved:', preserveRes);
Output:
{ name: 'GeeksforGeeks', website: 'www.geeeksforgeeks.org' }
Type is preserved: true
Using Lodash's cloneDeep function
In this approach, we are using Lodash's cloneDeep function to perform a deep clone of the object. Lodash's cloneDeep method is a robust solution for deep cloning objects, and TypeScript's type inference ensures that the type is preserved.
Syntax:
_.cloneDeep(value);
Example:
JavaScript
import _ from 'lodash';
function approach3Fn<T>(obj: T): T {
return _.cloneDeep(obj);
}
interface Person {
name: string;
details: {
age: number;
address: {
city: string;
country: string;
};
};
}
const person: Person = {
name: 'GeeksforGeeks',
details: {
age: 22,
address: {
city: 'Noida',
country: 'India'
}
}
};
const res = approach3Fn(person);
console.log(res);
const preserveRes: boolean = res instanceof Object;
console.log('Type is preserved:', preserveRes);
Output:
{
name: 'GeeksforGeeks',
details: {
age: 22,
address: {
city: 'Noida',
country: 'India'
}
}
}
Type is preserved: true
Using a Recursive Function
In this approach, we manually implement a recursive function to deep clone the object. This method allows us to handle more complex cloning requirements and ensure that the type structure of the original object is preserved.
Example: The below example uses a custom recursive function to deep-clone an object and preserve its type with TypeScript.
JavaScript
interface Person {
name: string;
details: {
age: number;
address: {
city: string;
country: string;
};
};
}
const person: Person = {
name: 'GeeksforGeeks',
details: {
age: 22,
address: {
city: 'Noida',
country: 'India'
}
}
};
const clonedPerson = deepClone(person);
const preserveRes = clonedPerson instanceof Object;
console.log(clonedPerson);
console.log("Type is preserved:", preserveRes);
Output:
{
name: 'GeeksforGeeks',
details: {
age: 22,
address: {
city: 'Noida',
country: 'India'
}
}
}
Type is preserved: true
Similar Reads
How to Check the Type of an Object in Typescript ?
When working with TypeScript, understanding how to check the type of an object is crucial for ensuring type safety and maintaining code integrity. TypeScript, being a statically typed superset of JavaScript, provides several approaches to accomplish this task as listed below. Table of Content Using
3 min read
How to Create an Observable with a Delay in TypeScript ?
Creating observables with delays is a common requirement in TypeScript applications, especially when dealing with asynchronous operations. To achieve this, we leverage the power of the rxjs library. What is rxjs library?The RxJS library is a powerful reactive programming library for JavaScript and T
3 min read
How to Create a Typed Array from an Object with Keys in TypeScript?
Creating a typed array from the keys of an object in TypeScript ensures that your application maintains type safety, particularly when interacting with object properties. Here we'll explore different approaches to achieve this using TypeScript's built-in Object methods. Below are the approaches used
3 min read
How to Define Strongly Type Nested Object Keys with Generics in TypeScript ?
We will look into the effective use of generics in TypeScript to ensure type safety when working with nested objects. By employing generics, developers can establish strongly typed keys for nested objects, significantly reducing the likelihood of runtime errors and enhancing code maintainability. Ta
2 min read
How to Declare Specific Type of Keys in an Object in TypeScript ?
In TypeScript, object definitions can include specific key-value types using index signatures. You can declare specific types of keys in an object by using different methods as listed below: Table of Content Using Mapped TypesUsing InterfaceUsing Inline Mapped Types with typeUsing Record Utility Typ
3 min read
How to Create Objects with Dynamic Keys in TypeScript ?
In TypeScript, objects with dynamic keys are those where the key names are not fixed and can be dynamically determined at runtime. This allows the creation of flexible data structures where properties can be added or accessed using variables, providing more versatile type definitions. These are the
3 min read
How to Create TypeScript Generic Function with Safe Type Matching ?
In TypeScript, generic functions offer a powerful tool for creating flexible and reusable code that can work with various data types. However, ensuring type safety is crucial to prevent runtime errors and maintain code reliability. These are the following approaches:Table of Content Using Type const
4 min read
TypeScript Object Type Excess Property Checks
In this article, we are going to learn about Object Type Index Signatures in Typescript. TypeScript is a popular programming language used for building scalable and robust applications. In TypeScript, excess property checks refer to the behavior where TypeScript checks for extra or unexpected proper
3 min read
How to Check if an Object is Empty in TypeScript ?
In TypeScript, it's common to encounter scenarios where you need to determine if an object is empty or not. An empty object typically means it contains no properties or all its properties are either undefined or null. Below are the methods to check if an object is empty or not in TypeScript: Table o
3 min read
How to Create Deep Readonly Type in Typescript?
In TypeScript, the readonly access modifier is a powerful tool that ensures immutability by marking properties of a class as immutable. Once a property is markedreadonly, it cannot be reassigned. This is highly useful for maintaining consistent and safe data structures, especially in scenarios such
3 min read