2015-11-13 104 views
1

我正在嘗試使用updeep庫。使用updeep的一個典型的例子是這樣的:TypeScript中的超類型約束條件

var person = { 
    name: { 
    first: 'Jane', 
    last: 'West' 
    } 
}; 

var result = u({ name: { first: 'Susan' } }, person); 

這裏的想法是,result將是person但隨着name.first變化值的克隆。你可以想像這個功能,u,以打字稿定義爲:

function u<T>(changes: {}, obj: T): T { ... } 

這捕獲的事實,第二個參數的類型也是該函數的返回類型。但它不表示的是changes應該是超級類型T

我想要的是一些類型檢查第一個參數。問題是changes爭論中存在的值應全部出現在T類型參數中,並與其對應的類型相匹配。表達這允許我們檢查changes參數以確保它對於類型TT的超級類型)有意義。

我不確定這是否可以在TypeScript中使用。在像Java這樣的語言中,您有關鍵字super,它可以用來描述類型參數的約束。

雖然打字稿不允許它,這樣的表現,我想什麼:

function u<T extends U,U extends {}>(changes: U, obj: T): T { ... } 

有誰知道如何表達這樣的一個建議嗎?擁有用於執行這種轉換的類型安全系統將是非常好的。

謝謝。

回答

0

有一個開放的問題,這樣的事情,所謂的「局部類型」在這裏:https://github.com/Microsoft/TypeScript/issues/4889

Facebook的流量也有類似(但intentionally undocumented)$形狀<>類型,它可以在分型可以看出對陣營的setState()

所以基本上,沒有,沒有這樣的功能,可以自動做到這一點。但是,你可以種解決它通過手動這樣做:

interface IPartialPerson { 
    name?: { 
    first?: string; 
    last?: string; 
    }; 
    someOptionalProperty?: string; 
} 

interface IPerson extends IPartialPerson { 
    name: { 
    first: string; 
    last: string; 
    }; 
} 

就個人而言,我更喜歡甚至避免後期,只是使用可選的屬性儘可能。強制性的財產並不能真正保護你免受任何傷害。即使它們看起來像,它們也不是non-nullable

+0

雖然確實這些是不可空的,但您仍然在這裏放棄一定程度的類型安全性。例如,當我在React中創建一個組件時,我指定了一個'props'類型。無論何時我在TSX中實例化該類型,因此都需要任何不是可選的。該要求由編譯器執行。讓所有東西都可選真的會爲各種可能造成混亂的「半成品」實例敞開大門。誠然,它們可以是'null',但是我必須明確地使它們成爲'null'**。 –

+0

@MichaelTiller我認爲它們有時會很有用,而且我確實傾向於在React道具中使用非可選屬性(以及propTypes中的isRequired設置!)。 但是我擔心,因爲它們會增加更多類型的安全性,所以請避免讓我自己(以及任何人閱讀代碼)假設可選屬性受到空值的保護。 – DallonF