2016-12-15 44 views
4

對象傳播廣泛用於更新實用的風格舊的對象,像這樣:如何輸入,安全地使用對象價差打字稿更新不可變對象

let o1 = { x: 5, y: 6 }; 
let o2 = { ...o1, y: 10 }; 
alert(JSON.stringify(o2)); 

在新的打字稿2.1我們現在的對象蔓延實施但不同於簡單的對象字面它允許有未知屬性:

interface Point { x: number, y: number } 

let o1: Point = { x: 5, y: 6 }; 

//ERROR: Object literal may only specify known properties 
let o2: Point = { x: 5, y: 6, z: 10 }; 

// OK: had I wanted to update y, but misspeled it, 
// I would get new "z" prop instead of compiler error which I would prefer to have: 
let o3: Point = { ...o1, z: 10 }; 

alert(JSON.stringify(o3)); 

所以,這裏是一個問題:如何鍵入安全地使用對象價差打字稿更新的對象?或者更常見的問題:如何更新TypeScript 2.1中的函數(不可變)和類型安全的方法中的對象?

回答

6

對象擴展允許使用現有的或新的鍵來擴展基礎對象。與Object.assign一樣。這是JS的動態本質。

如果這不是你想要的(對我來說往往是這種情況),那麼不要使用對象傳播或分配。

你可以在本地寫一個實用功能,像這樣:

function update<T, K extends keyof T>(obj: T, updateSpec: Pick<T, K>): T { 
    const result = {} as T 
    Object.keys(obj).forEach(key => result[key] = obj[key]) 
    Object.keys(updateSpec).forEach((key: K) => result[key] = updateSpec[key]) 
    return result 
} 

我認爲這是你想要的語義。

+0

我可以請你逐行解釋你在那裏做了什麼?我很想了解更多關於TS的知識,但我不明白你所寫的構造。提前致謝。 –

+0

我試圖在博客文章中解釋這一點:http://www.nechai.net/2017/01/10/updating-an-immutable-object-in-typescript/ –

+0

糟糕,忘記了那個答案。好博客帖子亞歷山大! – AlexG