TypeScript - Never: 了解底層類型
Hello, 有志青年程式設計師!今天,我們將深入TypeScript中一個較為神秘的類型:never
類型。如果你是程式設計的新手,別擔心——我會逐步引導你理解這個概念,就像我這些年來對無數學生所做的那樣。所以,拿起你喜歡的飲料,讓我們一起踏上這場令人興奮的TypeScript之旅吧!
What is the never type?(什么是never类型?)
TypeScript中的never
類型通常被稱為"底層類型"或"空類型"。它代表一個永不會發生的類型。現在,你可能會想:"我們為什麼需要一個從不發生的類型呢?" 嗯,我好奇的朋友們,這比你想像的還要有用!
When is never used?(何时使用never?)
- 總是代表不可能的情況
- 處理徹底的檢查
- 在永不返回的函數中
讓我們看一些例子來使這些概念更清晰。
Example 1: Representing Impossible Scenarios(例子1:表示不可能的情况)
function throwError(message: string): never {
throw new Error(message);
}
let result = throwError("Oops! Something went wrong!");
console.log(result); // 這行代碼永遠不會被達到
在這個例子中,throwError
函數保證會抛出一個錯誤並永遠正常返回。因此,它的返回類型是never
。
把它想像成這樣:如果你在烤蛋糕,配方說"烤到永遠",你就知道那個蛋糕不會從烤箱裡出來!
Example 2: Exhaustive Checks(例子2:彻底的检查)
type Shape = "circle" | "square" | "triangle";
function getArea(shape: Shape): number {
switch (shape) {
case "circle":
return Math.PI * Math.pow(5, 2);
case "square":
return 10 * 10;
case "triangle":
return (10 * 5) / 2;
default:
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
在這裡,never
幫助我們確保我們已經覆蓋了所有可能的形狀。如果我們在Shape
類型中添加了一個新形狀但忘記在getArea
中為它添加一個案例,TypeScript會給我們一個錯誤。這就像有一個有用的助手在提醒你忘記了什麼!
Example 3: Functions That Never Return(例子3:永不返回的函数)
function infiniteLoop(): never {
while (true) {
console.log("This loop never ends!");
}
}
這個函數將永遠運行(或者直到你的電腦耗盡記憶體)。因为它從不結束執行,所以它的返回類型是never
。這就像告訴你的朋友你會"永遠"停止說話——他們知道他們會有一段長時間的對話!
The never type vs. void(never类型与void类型的区别)
現在,你可能會想:"never
和void
有什麼區別?" 好問題!讓我們來分析一下。
void(void类型)
void
類型用於當函數不返回任何值,但它會完成其執行。
function logMessage(message: string): void {
console.log(message);
}
logMessage("Hello, TypeScript!"); // 這個函數返回undefined
never(never类型)
另一方面,never
類型用於當函數從不完成其執行或總是抛出錯誤。
function failwithError(message: string): never {
throw new Error(message);
}
failwithError("This function never returns!");
這樣想:void
就像去一家商店並空手而歸,而never
就像踏上沒有目的地的旅程——你從不回來!
Practical Uses of never(never的实用用途)
讓我們看看一些never
可以派上用場的更實際的例子。
Example 4: Type Guards(例子4:类型守卫)
type Square = { kind: "square", size: number };
type Circle = { kind: "circle", radius: number };
type Shape = Square | Circle;
function assertNever(x: never): never {
throw new Error("Unexpected object: " + x);
}
function getArea(shape: Shape) {
switch (shape.kind) {
case "square": return shape.size * shape.size;
case "circle": return Math.PI * shape.radius ** 2;
default: return assertNever(shape); // 如果shape既不是Square也不是Circle,則出錯
}
}
在這個例子中,assertNever
幫助我們捕捉到可能錯過的任何情況。這就像在學習擲骰子時有一個安全網!
Example 5: Unreachable Code Detection(例子5:不可达代码检测)
function neverReaches(): never {
while (true) {
// 一些操作
}
console.log("This line will never be reached"); // TypeScript错误
}
TypeScript足夠聰明,知道console.log
語句永遠不會達到,並會給你一個錯誤。這就像有一個GPS告訴你當你試圖開車到一個不存在的地方時!
Methods and Properties of never(never的方法和属性)
現在,你可能會想,"never"有沒有自己的方法和屬性。事實是,"never"沒有自己的方法和屬性,因为它代表一個永不會發生的類型。然而,它仍然是TypeScript類型系統中重要的一部分。
這裡有一個總結你可以(或不可以)與"never"進行的操作的表格:
操作 | 結果 | 解釋 |
---|---|---|
賦值給 "never" | ✅ 允許 | 任何類型都可以賦值給 "never" |
將 "never" 賦值給其他類型 | ❌ 不允許 | "never" 不能賦值給任何其他類型 |
在 "never" 上調用方法 | ❌ 不允許 | 因為 "never" 應該從不發生,所以你不能在它上面調用方法 |
在聯合中使用 "never" | ✅ 允許但沒有影響 | 在聯合類型中 "never" 被忽略 |
在交集中使用 "never" | ✅ 允許並且結果為 "never" | 任何類型與 "never" 的交集結果都是 "never" |
Conclusion(结论)
親愛的學生們,這就是我們對"never"類型的探索,我們一起走過了它的角落和細節。記住,"never"就像那個總是取消計劃的朋友——他從不露面,但仍然重要的是要把它放在心上!
理解"never"可能起初看起來有些複雜,但隨著練習,你會發現它是你TypeScript工具箱中無價的工具。它幫助你的代碼變得更健壯,捕捉潛在的錯誤,甚至讓你更深入地思考你的函數行為。
繼續編程,持續學習,並且在TypeScript中不要拒絕嘗試新事物!直到下一次見面,願你的編譯錯誤少之又少,類型推斷強大無比!
Credits: Image by storyset