假設我有一個現有的物件 obj1 = {a: 'A', b: 'B', c: 'C', d: 'D'}
我有另一個物件,比如 obj2 = {b: 'B2', c: 'C2', d: 'D2', e: 'E2'}
現在我想有選擇地從obj2to復制幾個屬性的值obj1,對于 中的其余屬性obj1,我希望它們保持不變。
現在,假設我想復制 propertiesb和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's 型別的屬性的某種方法
uj5u.com熱心網友回復:
我的建議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;
}
該函式在目標物件的型別以及您要從源復制到目標物件的鍵名的型別方面是通用的。我假設您想要求從源復制的屬性應該與目標中已有的屬性具有相同的型別;例如,您不會將屬性從 type 的源復制到type的目標,因為您會將a寫入a并違反目標的型別。TK"a"{a: number}{a: string}numberstring
請注意,我們不需要源物件正好是T; 它只有與同意T在所有的按鍵K。也就是說,我們只能說,它必須Pick<T, K>使用的Pick<T, K>工具型別。
并注意我們肯定是通過在關鍵字串陣列,該編譯器會推斷出不一樣string,但專門為工會字串字面型別它們的子集keyof T(使用該keyof型別的操作來獲取已知密鑰的工會的T)。因此,如果您傳入["b", "d"],編譯器會將其推斷為型別Array<"b" | "d">,而不僅僅是Array<string>. 這將為您提供您正在尋找的型別安全性,而無需擔心nameofJavaScript 中不存在的類似內容(并且在 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"]
)
Playground 鏈接到代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/361579.html
