Borislav Hadzhiev
Sun Feb 27 2022·3 min read
Photo by Toa Heftiba
To use the Object.assign()
method in TypeScript, pass a target object as the
first parameter to the method and one or more source objects, e.g.
const result = Object.assign({}, obj1, obj2)
. The method will copy the
properties from the source objects to the target object.
const obj1 = { name: 'Tom' }; const obj2 = { country: 'Chile' }; // 👇️ const result: { name: string; } & { country: string; } const result = Object.assign({}, obj1, obj2); console.log(result); // 👉️ {name: 'Tom', country: 'Chile'}
We used the Object.assign method to merge two source objects into a target object.
target
object, to which the properties of the source objects are applied.The next parameters are source
objects - objects containing the properties you
want to apply to the target
.
In the example, we passed an empty object as the target
, because you should
generally avoid mutating objects as it introduces confusion.
For example, we could've passed obj1
as the target and obj2
as the source.
const obj1 = { name: 'Tom' }; const obj2 = { country: 'Chile' }; // 👇️ const result: { name: string; } & { country: string; } const result = Object.assign(obj1, obj2); console.log(result); // 👉️ {name: 'Tom', country: 'Chile'} console.log(obj1); // 👉️ {name: 'Tom', country: 'Chile'} // ⛔️ Error: Property 'country' does not // exist on type '{ name: string; }'.ts(2339) console.log(obj1.country);
Note that the target
object is changed in place.
This is especially problematic when using TypeScript, because obj1
was changed
in place, but it's type is still {name: string}
, even though the object
contains a country
property as well.
Object.assign
method.TypeScript uses an
intersection type
to type the return value of the Object.assign()
method.
const obj1 = { name: 'Tom' }; const obj2 = { country: 'Chile' }; // 👇️ const result: { name: string; } & { country: string; } const result = Object.assign({}, obj1, obj2); console.log(result); // 👉️ {name: 'Tom', country: 'Chile'}
In other words, the return value has a type that has all of the members of all
of the objects you passed to the Object.assign
method.
When you use the Object.assign
method with objects that have the same
properties, the properties are overwritten by objects that come later in the
parameter list.
const obj1 = { name: 'Tom' }; const obj2 = { name: 'James' }; // 👇️ const result: { name: string; } & { name: string; } const result = Object.assign({}, obj1, obj2); console.log(result); // 👉️ {name: 'James'} console.log(result.name); // 👉️ "James"
Both of the objects in the example have a property of name
, so the object that
is passed later in the parameters order wins.
You should also consider using the
spread syntax (...)
as a replacement for Object.assign
.
const obj1 = { name: 'Tom' }; const obj2 = { country: 'Chile' }; // 👇️ const result: {country: string;name: string;} const result = { ...obj1, ...obj2 }; console.log(result); // 👉️ {name: 'Tom', country: 'Chile'}
The spread syntax (...) unpacks the properties of the objects into a new object.
Object.assign()
method.This is generally a better approach, because you can't shoot yourself in the
foot by forgetting to provide an empty object as the first parameter of the
Object.assign
method and unintentionally mutating an object in place.
You can unpack as many objects as necessary into a new object and if two objects have the same property, the object that comes later wins.
const obj1 = { name: 'Tom' }; const obj2 = { name: 'James' }; // 👇️ const result: {name: string;} const result = { ...obj1, ...obj2 }; console.log(result); // 👉️ {name: 'James'}
Both of the objects have the name
property, so the latter object wins.