在 TypeScript 中合并对象
How to merge Objects in TypeScript
使用扩展语法 (…) 合并 TypeScript 中的对象,例如
const obj3 = { ...obj1, ...obj2 }
. 最终对象的类型将被成功推断,因此尝试向其添加或删除属性将导致类型检查器显示错误。
索引.ts
const obj1 = { name: 'Tom', age: 30 }; const obj2 = { country: 'Chile' }; // 👇️ const obj3: {country: string; name: string; age: number;} const obj3 = { ...obj1, ...obj2 }; console.log(obj3); // 👉️ {name: 'Tom', age: 30, country: 'Chile'}
我们使用
扩展语法 (…)
将属性从 2 个对象解包到第三个对象中。
请注意,即使我们没有明确地向任何对象添加类型,TypeScript 也能够推断出类型。
例如,如果我尝试向对象添加新的键值对obj3
或尝试从对象中删除键,TypeScript 将显示错误。
索引.ts
const obj1 = { name: 'Tom', age: 30 }; const obj2 = { country: 'Chile' }; // 👇️ const obj3: {country: string; name: string; age: number;} const obj3 = { ...obj1, ...obj2 }; console.log(obj3); // 👉️ {name: 'Tom', age: 30, country: 'Chile'} // ⛔️ 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'];
类型检查器显示错误,因为最终对象的类型已经设置为country
,name
和age
属性设置为特定类型。
但是,只要提供类型正确的值,就可以更新对象上存在的属性。
索引.ts
const obj1 = { name: 'Tom', age: 30 }; const obj2 = { country: 'Chile' }; // 👇️ const obj3: {country: string; name: string; age: number;} const obj3 = { ...obj1, ...obj2 }; console.log(obj3); // 👉️ {name: 'Tom', age: 30, country: 'Chile'} obj3.name = 'Alice'; obj3.age = 29; console.log(obj3); // 👉️ {name: 'Alice', age: 29, country: 'Chile'}
合并对象时,顺序很重要,因为如果两个对象具有相同的键,则属性较晚解包的对象获胜。
索引.ts
const obj1 = { name: 'Tom', age: 30 }; const obj2 = { name: 'Alice' }; // 👇️ const obj3: {name: string; age: number} const obj3 = { ...obj1, ...obj2 }; console.log(obj3); // 👉️ {name: 'Alice', age: 30}
这两个对象都具有该name
属性,但是 的键obj2
稍后会被解包,因此它的值会覆盖 中的name
属性
值obj1
。
您可能还会看到Object.assign()
用于在 TypeScript 中合并对象的方法。
索引.ts
const obj1 = { name: 'Tom', age: 30 }; const obj2 = { country: 'Chile' }; // 👇️ const obj3: {name: string; age: number} & {country: string} const obj3 = Object.assign({}, obj1, obj2); console.log(obj3); // 👉️ {name: 'Tom', age: 30, country: 'Chile'}
Object.assign
方法采用的第一个参数
是target
对象——源对象的属性应用到的对象。
该方法采用的下一个参数是一个或多个源对象。
TypeScript 还能够使用交集类型推断新对象的类型。
交集类型是使用
&
与号定义的,用于组合现有的对象类型。您可以&
根据需要多次使用该运算符来构造一个类型。如果您尝试向对象添加新属性或删除现有属性,类型检查器将抛出异常。
索引.ts
const obj1 = { name: 'Tom', age: 30 }; const obj2 = { country: 'Chile' }; // 👇️ const obj3: {name: string; age: number} & {country: string} const obj3 = Object.assign({}, obj1, obj2); console.log(obj3); // 👉️ {name: 'Tom', age: 30, country: 'Chile'} // ⛔️ 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'];
这与使用扩展语法 (…) 的方式相同。
只要提供正确类型的值,您仍然可以更新对象的现有属性。
索引.ts
const obj1 = { name: 'Tom', age: 30 }; const obj2 = { country: 'Chile' }; // 👇️ const obj3: {name: string; age: number} & {country: string} const obj3 = Object.assign({}, obj1, obj2); console.log(obj3); // 👉️ {name: 'Tom', age: 30, country: 'Chile'} obj3.name = 'Alice'; console.log(obj3); // 👉️ {name: 'Alice', age: 30, country: 'Chile'}
目标对象的属性将被参数顺序中具有相同属性的其他对象覆盖。
索引.ts
const obj1 = { name: 'Tom', 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}
此行为也与传播语法 (…) 一致。