[英]How to copy values of only a subset of object properties to another existing object in TypeScript
假设我有一个现有的对象obj1 = {a: 'A', b: 'B', c: 'C', d: 'D'}
我有另一个对象,例如obj2 = {b: 'B2', c: 'C2', d: 'D2', e: 'E2'}
现在我想选择性地从只有几个属性的值复制obj2
到obj1
中,对于性能的休息obj1
,我希望他们保持不变。
现在,假设我想复制属性b
和d
的值。 我想做类似的事情
obj1 = {a: 'A', b: 'B', c: 'C', d: 'D'};
obj2 = {b: 'B2', c: 'C2', d: 'D2', e: 'E2'};
copyPropertyvalues(
obj2, // source
obj1, // destination
[obj2.b, obj2.d] // properties to copy >> see clarification below
); // should result in obj1 = {a: 'A', b: 'B2', c: 'C', d: 'D2'}
这个方法怎么写? 请注意,我也不想将属性列表提供为字符串,因为我希望尽可能保证编译时安全。
所以这里的基本问题是:
'b', 'd'
)并尽可能利用TypeScript
安全性 当我在(伪)代码示例中说obj2.b
左右时
obj2.b
b
实际上是obj2
类型的属性的某种方法我对copyPropertyvalues()
建议是这样的:
function copyPropertyvalues<T, K extends keyof T>(s: Pick<T, K>, d: T, ks: K[]) {
ks.forEach(k => d[k] = s[k]);
return d;
}
该函数在目标对象的类型T
以及您要从源复制到目标对象的键名的类型K
中是通用的。 我假设您想要求从源复制的属性应该与目标中已有的属性具有相同的类型; 例如,你不会复制"a"
从类型的源属性{a: number}
到类型的目的地{a: string}
,因为你会写一个number
到string
和违反的类型目的地。
请注意,我们不需要源对象正好是T
; 它只需要在K
中的所有键上与T
一致。 也就是说,我们只说它必须是Pick<T, K>
使用Pick<T, K>
实用程序类型。
并注意我们肯定是通过在关键字符串数组,该编译器会推断出不一样string
,而是专门为工会字符串字面类型它们的子集keyof T
(使用的keyof
型运营商获得工会T
的已知键)。 因此,如果您传入["b", "d"]
,编译器会推断它的类型为Array<"b" | "d">
Array<"b" | "d">
而不仅仅是Array<string>
。 这将为您提供您正在寻找的类型安全性,而无需担心诸如nameof
类的nameof
,它在 JavaScript 中不存在(并且在 TypeScript 中不存在,直到它存在,请参阅microsoft/TypeScript#1579 )。
好的,让我们试一试:
copyPropertyvalues(
obj2, // source
obj1, // destination
["b", "d"] // properties to copy
);
console.log(obj1)
/* {
"a": "A",
"b": "B2",
"c": "C",
"d": "D2"
} */
看起来它的行为就像你想要的那样。 如果你把错误的键放在那里,你会得到编译时错误:
copyPropertyvalues(
obj2, // error!
obj1,
["a"]
)
copyPropertyvalues(
obj2,// error!
obj1,
["z"]
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.