網站搜尋

TypeScript:在沒有型別變數的情況下使用條件型別


給定一個聯合:

type Status =
    | "Loading"
    | "Success"
    | "Error"

我原本期望這個能夠運作:

type Success = Status extends "Success" ? Status : never;
const s: Success = "Success";

然而,上述結果導致

類型 'string' 無法分配給類型 'never'。

然而,如果我使用我認為是等價的東西:

type E<T, U> = T extends U ? T : never;
type Success = E<Status, "Success">;

const s: Success = "Success";

它可以順利編譯。現在,我知道我創建的 E 類型基本上就是 Extract 的運作方式。我只是想了解,為什麼它在上述兩種情況下的行為會不同。

答案#1

這是因為條件類型會在聯合類型上分配,所以 E<"Loading" | "Success" | "Error", "Success"> 被解析為

E<"Loading", "Success"> | E<"Success", "Success"> | E<"Error", "Success">
// "Success"

而不是作為

"Loading" | "Success" | "Error" extends "Success" ? "Loading" | "Success" | "Error" : never
// never

欲了解更多資訊,請參閱 TypeScript 手冊中關於分配條件型別的章節。