簡體   English   中英

在 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實現,其中valuestring類型 - 我想避免這種情況。

這在當前版本的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM