[英]Do discriminated unions only work with literal types?
在下面的代碼段中,我無法使用typeof
運算符區分聯合類型。
function f(arg: { status: number; one: boolean } | { status: string; two: boolean }) {
if (typeof arg.status === "number") {
return arg // arg is still of the union type and is not narrowed
} else {
return arg // similar here
}
}
但是如果將status
更改為某種文字類型,則可以區分聯合。
function f(arg: { status: "one"; one: boolean } | { status: "two"; two: boolean }) {
if (arg.status=== "one") {
return arg // here arg is of type { status: "one"; one: boolean }
} else {
return arg // and here it's of type { status: "two"; two: boolean }
}
}
所以,我想知道為什么它在第一種情況下不起作用,是歧視聯合只適用於文字類型還是有別的?
我試圖在文檔中查找是否在某處提到可區分聯合僅適用於文字類型,但我找不到任何東西。
嗯,這是 Typescript 目前存在的一種限制。 在 Typescript Github存儲庫中已經討論過幾次,所以我將使用那里的一些響應。
首先,您應該知道:
類型保護不會將類型縮小傳播到父對象。 縮小僅在訪問縮小屬性時應用,這就是為什么破壞 function 有效,但參考 function 無效。 縮小父級將涉及合成昂貴的新類型。
所以基本上如果你使用下面的代碼,你會看到 TS 確實能夠縮小該特定屬性的類型:
function f1(arg: { status: number; one: boolean } | { status: string; two: boolean }) {
if (typeof arg.status === "number") {
const st = arg.status // st: number
}
}
縮小父 object 僅在特定情況下進行,此時該屬性被視為聯合的判別式。 在以下情況下,屬性被視為判別屬性:
1- 該屬性是一種文字類型,如此處所述的可區分聯合類型。
2- 如果聯合類型的聯合類型包含至少一個單元類型且沒有可實例化的類型,則聯合類型的屬性將成為判別屬性,如此處所述Allow non-unit types in union discriminants 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.