How to merge Objects in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 27, 2024
4 min

banner

# Merging Objects in TypeScript

Use the spread syntax (...) to merge objects in TypeScript.

The type of the final object will successfully be inferred, so trying to add or remove properties causes the type checker to show an error.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { country: 'Chile' }; // ๐Ÿ‘‡๏ธ const obj3: {country: string; name: string; age: number;} const obj3 = { ...obj1, ...obj2 }; // ๐Ÿ‘‡๏ธ { name: 'Bobby Hadz', age: 30, country: 'Chile' } console.log(obj3);

merging objects in typescript

The code for this article is available on GitHub

We used the spread syntax (...) to unpack the properties from 2 objects into a third.

Even though we haven't explicitly added types to any of the objects, TypeScript is able to infer the type.

For example, if I try to add a new key-value pair to obj3 or try to delete a key from the object, TypeScript will show an error.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { country: 'Chile' }; // ๐Ÿ‘‡๏ธ const obj3: {country: string; name: string; age: number;} const obj3 = { ...obj1, ...obj2 }; // ๐Ÿ‘‡๏ธ {name: 'Bobby hadz', age: 30, country: 'Chile'} console.log(obj3); // โ›”๏ธ Error: Property 'test' does not exist // on type '{ country: string; name: string; age: number; }'. obj3.test = 'hello'; // โ›”๏ธ Error: The operand of a 'delete' operator must be optional. delete obj3['name'];

The type checker shows an error because the final object is already typed to have the country, name and age properties set to specific types.

However, you are able to update properties that exist on the object, as long as you provide a value that is the correct type.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { country: 'Chile' }; // ๐Ÿ‘‡๏ธ const obj3: {country: string; name: string; age: number;} const obj3 = { ...obj1, ...obj2 }; // ๐Ÿ‘‡๏ธ {name: 'Bobby Hadz', age: 30, country: 'Chile'} console.log(obj3); obj3.name = 'Alice'; obj3.age = 29; console.log(obj3); // ๐Ÿ‘‰๏ธ {name: 'Alice', age: 29, country: 'Chile'}

When merging objects, the order is important because if two objects have the same key, the object whose properties are unpacked later wins.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { name: 'Alice' }; // ๐Ÿ‘‡๏ธ const obj3: {name: string; age: number} const obj3 = { ...obj1, ...obj2 }; console.log(obj3); // ๐Ÿ‘‰๏ธ {name: 'Alice', age: 30}

Both of the objects have the name property, however, the keys of obj2 are unpacked later, so its value overrides the value of the name property in obj1.

# Merging Objects in TypeScript with Object.assign()

You might also see the Object.assign() method used to merge objects in TypeScript.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { country: 'Chile' }; // ๐Ÿ‘‡๏ธ const obj3: {name: string; age: number} & {country: string} const obj3 = Object.assign({}, obj1, obj2); // ๐Ÿ‘‡๏ธ {name: 'Bobby Hadz', age: 30, country: 'Chile'} console.log(obj3);

merging objects in typescript with object assign

The code for this article is available on GitHub

The first parameter the Object.assign method takes is the target object - the object to which the properties of the source objects are applied.

The next parameters the method takes are one or more source objects.

TypeScript is also able to infer the type of the new object using an intersection type.

Intersection types are defined using an ampersand & and are used to combine existing object types. You can use the & operator as many times as necessary to construct a type.

If you try to add a new property to the object or delete an existing property, the type checker will throw an error.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { country: 'Chile' }; // ๐Ÿ‘‡๏ธ const obj3: {name: string; age: number} & {country: string} const obj3 = Object.assign({}, obj1, obj2); // ๐Ÿ‘‡๏ธ {name: 'Bobby Hadz', age: 30, country: 'Chile'} console.log(obj3); // โ›”๏ธ Error: Property 'test' does not exist // on type '{ country: string; name: string; age: number; }'. obj3.test = 'hello'; // โ›”๏ธ Error: The operand of a 'delete' operator must be optional. delete obj3['name'];

This works in the same way as using the spread syntax (...).

You are still able to update the existing properties of the object, as long as you provide a value of the correct type.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { country: 'Chile' }; // ๐Ÿ‘‡๏ธ const obj3: {name: string; age: number} & {country: string} const obj3 = Object.assign({}, obj1, obj2); // ๐Ÿ‘‡๏ธ {name: 'Bobby Hadz', age: 30, country: 'Chile'} console.log(obj3); obj3.name = 'Alice'; console.log(obj3); // ๐Ÿ‘‰๏ธ {name: 'Alice', age: 30, country: 'Chile'}

provide value of correct type

The properties of the target object are overwritten by other objects that have the same properties later in the parameter order.

index.ts
const obj1 = { name: 'Bobby Hadz', age: 30 }; const obj2 = { name: 'Alice' }; // ๐Ÿ‘‡๏ธ const obj3: {name: string; age: number} & {country: string} const obj3 = Object.assign({}, obj1, obj2); console.log(obj3); // ๐Ÿ‘‰๏ธ {name: 'Alice', age: 30}

This behavior is also consistent with the spread syntax (...).

Want to learn more about working with objects in TypeScript? Check out these resources: How to compare Objects in TypeScript,How to Add a property to an Object in TypeScript.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev