網站搜尋

TypeScript - 使用條件型別從自身/自身物件推斷/提取型別


我目前在我的 .d.ts 中有這些類型。

type TransactionRowTypes = {
    // transaction row types
}
type UserDataTypes = {
    // user data types
}
type InventoryRowTypes = {
    // inventory row types
}

type EventClientEvent = {
    event: 'transactions' | 'userchange' | 'inventory';
    time: number;
    payload: Array<any>;
};

我想要這樣做,例如,當我的 EventClientEvent.event 是 transactions 時,我希望 payload 的類型是 TransactionRowTypes。如果 EventClientEvent.event 是 userchange,我希望我的 payload 的類型是 UserDataTypes,以此類推。我在嘗試理解如何在其自身的物件類型上使用條件類型時遇到了一些問題,或者我是否正確使用了它。我有這個類型提取器,但我不確定如何使用它。

type EventName<T extends {event: string}> = T["event"];

有人可以指給我正確的方向嗎?謝謝

答案#1

條件型別對這個並沒有真正幫助。看起來你希望 EventClientEvent 成為以下形式的判別聯合類型:

type EventClientEvent = {
    event: "transactions";
    time: number;
    payload: TransactionRowTypes[];
} | {
    event: "userchange";
    time: number;
    payload: UserDataTypes[];
} | {
    event: "inventory";
    time: number;
    payload: InventoryRowTypes[];
}
 

你可以手動定義,但如果你想能夠新增/更改 event/payload 配對,你可以改為寫一個映射介面,如

interface EventMapping {
  transactions: TransactionRowTypes;
  userchange: UserDataTypes;
  inventory: InventoryRowTypes
}

然後使用它來計算EventClientEvent,像這樣:

type EventClientEvent = { [K in keyof EventMapping]:
  {
    event: K;
    time: number;
    payload: Array<EventMapping[K]>
  }
}[keyof EventMapping]

這是一個由 microsoft/TypeScript#47109 創造的 分配型別物件,我們會建立一個映射型別,然後立即使用該映射型別的鍵來索引它。它會將內部型別 {event: K; time: number; payload: Array<EventMapping[K]>} 分配 到 K 中的聯合型別,在這個例子中,K 是 keyof EventMapping 或 "transactions" | "userchange" | "inventory"。

你可以驗證這個評估的結果與上面等效的類型相同。

到程式碼的遊樂場連結。