避免出現新增了聯合類型沒有對應的實作,目的就是寫出類型絕對安全的代碼。
TypeScript 2.0引入了一個新原始類型never。never類型表示值的類型從不出現。具體而言,never是永不傳回函數的傳回類型,也是變量在類型保護中永不為true的類型。
never類型具有以下特征:
- never是所有類型的子類型并且可以指派給所有類型。
- 沒有類型是never的子類型或能指派給never(never類型本身除外)。
- 在有明确never傳回類型注解的函數中,所有return語句(如果有的話)必須有never類型的表達式并且函數的終點必須是不可執行的。
比較直覺的代碼舉例:
interface Foo {
type: 'foo'
}
interface Bar {
type: 'bar'
}
type All = Foo | Bar
在 switch 當中判斷 type,TS 是可以收窄類型的 (discriminated union):
function handleValue(val: All) {
switch (val.type) {
case 'foo':
// 這裡 val 被收窄為 Foo
break
case 'bar':
// val 在這裡是 Bar
break
default:
// val 在這裡是 never
const exhaustiveCheck: never = val
break
}
}
注意在 default 裡面我們把被收窄為 never 的 val 指派給一個顯式聲明為 never 的變量。如果一切邏輯正确,那麼這裡應該能夠編譯通過。
但是假如後來有一天你的同僚改了 All 的類型:
type All = Foo | Bar | Baz
然而他忘記了在 handleValue 裡面加上針對 Baz 的處理邏輯,這個時候在 default branch 裡面 val 會被收窄為 Baz,導緻無法指派給 never,産生一個編譯錯誤。是以通過這個辦法,你可以確定 handleValue 總是窮盡 (exhaust) 了所有 All 的可能類型。
參考:知乎大佬們的回答