![](/img/trans.png)
[英]Is it possible to create a discriminated union using mapped types in TypeScript?
[英]Stricter union types when using mapped types in TypeScript
在映射中使用聯合類型時,我試圖使用映射類型來提供更多類型安全。 當使用屬性類型(例如['value']
)作為鍵( K
)的類型時,似乎沒有辦法在鍵/值之間提供類型安全。
我想避免手動創建一個獨特的模型來實現這一點。
代碼:
interface IAction { value: string; }
type ActionMapper<A extends IAction> = {
[K in A['value']]: A;
}
interface IActionOne { value: 'action_one' }
interface IActionTwo { value: 'action_two' }
type Actions = IActionOne | IActionTwo;
const reducerMap: ActionMapper<Actions> = {
action_one: { value: 'action_one' },
action_two: { value: 'action_one' }, // expecting this line to fail
}
我已經評論了我預計會失敗的行。
我覺得我應該能夠利用鍵( K in
)來提供正確的類型作為值。 但是,我目前使用A
,它提供IAction
實現,其中value
是string
類型 - 我想避免這種情況。
這在當前版本的 TypeScript 中可能嗎?
是的,可以做你想做的。
正如您所注意到的,您的問題是ActionMapper<A>
的屬性值始終為A
。 對於Actions
,這是一個聯合類型。 您真正想要做的是從A
提取與每個鍵K
匹配{value: K}
的成分。 幸運的是,有一個名為Extract
的預定義條件類型可以為您執行此操作。 讓我們重新定義ActionMapper<A>
:
type ActionMapper<A extends IAction> = {
[K in A['value']]: Extract<A, {value: K}>;
}
現在我們再試一次:
const reducerMap: ActionMapper<Actions> = {
action_one: { value: 'action_one' },
action_two: { value: 'action_one' }, // error!
// Type '"action_one"' is not assignable to type '"action_two"'.
}
你會得到你預期的錯誤。 希望有幫助。 祝你好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.