TypeScript 筆記:never 簡介


Posted by SimonAllen on 2021-08-18

上一篇 TypeScript 筆記簡單介紹了 unknown,而此篇改來介紹另一個特殊型別—— never:

never

never 型別是所有型別的子集,TypeScript 「所有」型別(甚至包括 any、null 與 undefined)都有包含 never 例外處理的狀態,其在 TypeScript 2.0 版提出,表示不存在值的型別,那怎樣會出現不存在值的型別呢?

最常見的情形有兩種:

  • 無法結束的函式方法
  • throw error 錯誤處理

無法結束的函式方法

無法結束函式方法情境,最常見就是函式內發生了無限迴圈的情況:

function infiniteLoop(){
   while(true){
   }
}

不過,上述程式碼在型別推論因為函式沒有回傳值,會被自動推論成 void。

可以這麼理解,當一個函式沒有返回值時,它的 return 值為 void 型別,但是當一個函式要 return 的返回值(例如表達式)卻沒有也永不返回(或者拋出錯誤),它的返回值為 never 型別。

若上述看起來很咬舌頭,可看看以下程式為例:

當函式被當成值指派給變數時,型別推論就幫我們推測變數為 never 型別。

const infinity = function infiniteLoop() {
  while (true) {}
};

throw error 錯誤處理

另一個情境就是 throw error 錯誤拋出時

function throwNewError(){
   throw new Error("error")
}

上述程式碼一樣在型別推論時,沒有回傳值被自動推論成 void。

當函式被當成值指派給變數時,型別推論就幫我們推測變數為 never 型別。

const error = function throwNewError() {
  throw new Error("error");
};

不管是型別推論或主動註記, never 可以幫助開發者提醒有可能會發生錯誤的狀況,非常貼心。

另外前面有提到所有型別(包括 any)都有包含 never 例外處理的狀態,所以在做聯合型別時,never 的優先度很低:

type stringAndNever = string | never;

聯合型別為 string,至於聯合型別與上方寫的 type 是做什麼,之後有機會再撰寫新的筆記季紹。

而和 any 相比

型別推論會推測此聯合型別為 any

和 undefined 相比

type undefinedAndNever = undefined | never;


聯合型別為 undefined。

和 null 聯合型別放一起也是 null,截圖就不放了。因為所有型別都包含著 never(作為例外處理的狀況),所以 never 永遠會被忽略,前面有提到 never 是表示不會存在值的型別,而 null 和 undefined 既是值也是型別,所以 never 也是 null 和 undefined 子集合。

正因如此,若我們主動註記 never 給變數再賦值

const a: never = 1
const b: never = "1"
const c: never = null
const d: never = undefined

這四個變數會全報錯,因為 never 是所有型別子集合,但其他型別不是 never 子集合,這個上對下的關係要搞清楚呦。

參考

TypeScript 新手指南
TypeScript: Typed JavaScript at Any Scale.
kobo 電子書:讓TypeScript成爲你前端開發的ACE!
Typescript 初心者手札


#TypeScript









Related Posts

MTR04_0723

MTR04_0723

[PySide6]主視窗

[PySide6]主視窗

MTR04_1111

MTR04_1111


Comments