never 是 TypeScript 中獨有的型別,本篇要來介紹 never 型別及其使用時機
The never type represents values which are never observed.
擷取自官方文件
never 直翻中文就是「從來沒有」、「絕不」
never 型別則表示一個函式或參數絕不會有回傳值
,經常使用在以下情境上:
never
function error(message: string): never {
throw new Error(message);
}
let a = function infiniteLoop() {
while (true) {
} // 無窮迴圈,永遠不會有回傳值
}
x: string | number
代表 x 只能是 string 或 number,這兩者外的都會走到 else
,此時 x
就會被推斷為 never
,表示剩下的情況「永遠不會發生」~function fn(x: string | number) {
if (typeof x === "string") {
// ... 略 ...
} else if (typeof x === "number") {
// ... 略 ...
} else {
return x; // ✅ x 推斷為 never
}
}
把上面例子的 else if
移除,最後的 x
則會被推斷為 number
function fn2(x: string | number) {
if (typeof x === "string") {
// ... 略 ...
} else {
return x; // ✅ x 推斷為 number
}
}
type AnotherType = never | string | number;
這個聯合型別推斷出來的結果為 string | number
, never 在任何聯合型別中都會因視為 empty type,而被忽略
登愣~這張圖又出場了
橫軸是「目標型別」;縱軸是「來源型別」
藍色勾勾(✓):來源型別可以被指派給目標型別
綠色勾勾(✓):tsconfig.json 中的 strictNullChecks 關閉時才能被指派
子型別(subtype)
function throwError(errMsg: string): never {
throw new Error(errMsg);
}
let exampleString: string = throwError("Error 1"); // ✅ Pass
let exampleNumber: number = throwError("Error 2"); // ✅ Pass
let exampleBoolean: boolean = throwError("Error 3"); // ✅ Pass
let strVal = 'hello'; // : string
let neverVal = function infiniteLoop() { // : never
while (true) {}
};
let result: never;
result = strVal; // ❌ Type 'string' is not assignable to type 'never'.
result = neverVal; // ❌ Type '() => never' is not assignable to type 'never'.
以上這兩個特性都可以解釋為何官方文件給了 never
一個這樣的說明
圖片改編自此文章
在 TypeScript 中,never
是 The Bottom Type,any
, unknown
則是 The Top Type
The Bottom Type 並非是 TypeScript 裡的專有名詞,在此 wiki 給的解釋是
In type theory, the bottom type of a type system is the type that is a subtype of all other types.
The bottom type may therefore be known as the zero, never or empty type.
never 型別為所有型別的 subtype,因為 never 沒有任何實際的回傳值,兼容了所有型別,因此在某些程式語言中被視為 0、never、空集合(empty type / empty set)
鐵人賽大大 Maxwell Alexius 的 這篇文章有給出更多 never 相關的例子,值得一看,不過有些範例的型別推論結果跟我目前在本地測試並不相同,猜測是是版本問題,那篇文章發佈時間距離現在已過 5 年,但 never 的概念、行為仍是不變的
每天的內容有推到 github 上喔