如何在打字稿中组合对象属性?
Posted
技术标签:
【中文标题】如何在打字稿中组合对象属性?【英文标题】:How to combine object properties in typescript? 【发布时间】:2016-08-30 18:27:58 【问题描述】:我想知道最好的方法,比如我有两个对象
var objectA =
propertyA: 1,
propertyB: 2
...
propertyM: 13
var objectB =
propertyN: 14,
propertyO: 15
...
propertyZ: 26
如果objectC是由
创建的var objectC = Object.assign(objectA, objectB);
如何声明/描述 objectC,以便编译器/IDE 知道它同时具有 objectA 和 objectB 的属性?
我想找到一种不需要为 objectA 和 objectB 定义接口的方法。我不想为同一个属性写两次声明和定义/评估。如果我在一个对象上有太多属性,这种冗余就很重要。
(有没有可以提取现有对象的接口/类型的算子?)
有可能吗?
【问题讨论】:
【参考方案1】:似乎这样可以解决问题:
var objectA =
propertyA: 1,
propertyB: 2,
.
. // more properties here
.
propertyM: 13
;
var objectB =
propertyN: 14,
propertyO: 15,
.
. // more properties here
.
propertyZ: 26
;
var objectC = ...objectA, ...objectB; // this is the answer
var a = objectC.propertyA;
var n = objectC.propertyN;
根据这篇文章:https://blog.mariusschulz.com/2016/12/23/typescript-2-1-object-rest-and-spread
此外,分解中变量的顺序很重要。 考虑以下几点:
var objectA =
propertyA: 1,
propertyB: 2, // same property exists in objectB
propertyC: 3
;
var objectB =
propertyX: 'a',
propertyB: 'b', // same property exists in objectA
propertyZ: 'c'
;
// objectB will override existing properties, with the same name,
// from the decomposition of objectA
var objectC = ...objectA, ...objectB;
// result: 'b'
console.log(objectC.propertyB);
// objectA will override existing properties, with the same name,
// from the decomposition of objectB
var objectD = ...objectB, ...objectA;
// result: '2'
console.log(objectD.propertyB);
【讨论】:
只是为了改进答案:这一行可以解决问题: var objectC = ...objectA, ...objectB; 如果两个对象中存在相同的键,我想更新 objectA 的属性。意味着如果键相同,那么它应该具有objectB的属性。这怎么可能? 阅读我的回答中的 cmets。基本上,它从左到右构造属性,其中每个新信息都会覆盖现有信息:var objectC = ...objectA, ...objectB;
。如果属性名称相同,objectB
中的属性将覆盖已经从objectA
分配的属性。
这行得通,因此回答了 OP,但是我担心现在没有与 objectD 或 objectC 关联的类型,当您尝试将其显式键入某些东西时(假设有这样的类型),它不会工作。有类型安全的方法吗?
@SrivathsaHarishVenkataramana 类型是从分配中推断出来的。所以 objectC 将有propertyB: string
,而 objectD 将推断它为propertyB: number
。您可以手动输入 C 和 D:type ABC = propertyA: number; propertyB: string | number; propertyC: number; propertyX: string; propertyZ: string;
或通过将 propertyB 设置为字符串或数字来仅输入其中之一。【参考方案2】:
所以编译器/IDE 知道它同时具有 objectA 和 objectB 的属性?
使用交集类型 + 泛型。例如。 from here
/**
* Quick and dirty shallow extend
*/
export function extend<A>(a: A): A;
export function extend<A, B>(a: A, b: B): A & B;
export function extend<A, B, C>(a: A, b: B, c: C): A & B & C;
export function extend<A, B, C, D>(a: A, b: B, c: C, d: D): A & B & C & D;
export function extend(...args: any[]): any
const newObj = ;
for (const obj of args)
for (const key in obj)
//copy all the fields
newObj[key] = obj[key];
return newObj;
;
更多
这里都提到了:https://basarat.gitbooks.io/typescript/content/docs/types/type-system.html
【讨论】:
谢谢。这似乎有效。但是,extend() 函数是在第 3 方库中定义的,有没有办法在其 d.ts 文件中覆盖 extend() 的这个特定定义? (我正在使用下划线 _.extend() )。 是的。只需修改underscore.d.ts
【参考方案3】:
(是否有可以提取接口/类型的运算符 现有对象?有可能吗?)
你应该选择typeof。
type typeA = typeof objectA;
type typeB = typeof objectB;
要使它们合并,您可以使用 basarat 已经指出的交集操作。
type typeC = typeA & typeB
【讨论】:
【参考方案4】:使用Typescript spread operator 转译为javascript Object.assign()
如果您需要深度树对象合并,您可以使用 best-global 包的更改功能
【讨论】:
【参考方案5】:试试这个..
const person = name: 'TRilok', gender: 'Male' ;
const tools = computer: 'Mac', editor: 'Atom' ;
const attributes = handsomeness: 'Extreme', hair: 'Brown', eyes: 'Blue' ;
const summary = ...person, ...tools, ...attributes;
【讨论】:
【参考方案6】:Lodash 有一个“扩展”功能,可以组合对象并让 Typescirpt 知道新对象具有您期望的类型。
const a = one: 1, two: 2 ;
const b = three: 3, four: 4 ;
const c = lodash.extend(a, b);
// c: one: 1, two: 2, three: 3, four: 4
【讨论】:
以上是关于如何在打字稿中组合对象属性?的主要内容,如果未能解决你的问题,请参考以下文章