- 文档
- 教程
【免费下载链接】typescript-book
The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.
导读
never是 TypeScript 类型系统中一个容易误解却极具价值的内置类型:它表示"永远不会发生的值"。在 The Concise TypeScript Book 中,never被用于标注永不返回的函数(如无限循环、抛错函数),并配合控制流分析实现穷尽性检查(exhaustiveness checking),让编译器在新增联合类型成员时立即报错。读完本文,你将掌握never的定义、三处典型用法、它与void/unknown的区分,以及如何用它守住联合类型的"最后一公里"。
一、never是什么:永不出现的值
根据原文档定义,never类型代表"永远不会出现的值"(values that never occur)。它被用来标注"永不返回"或"必然抛出错误"的函数与表达式。
把它放到类型系统"集合论"视角下看会更直观。仓库中的 exploring-the-type-system.md 将每种类型看作一个集合,并给出对应表:
| 集合术语 | TypeScript | 说明 |
|---|---|---|
| 空集(Empty set) | never | never中不包含除它自身之外的任何值 |
| 单元素集 | undefined/null/ 字面量类型 | 例如type X = 'X' |
| 有限集 | boolean/ 联合类型 | 如'up' \| 'down' |
| 无限集 | string/number/object | |
| 全集(Universal set) | any/unknown | any包含每个元素;unknown是any的类型安全版 |
因此,从集合视角看,never就是空集 ∅:没有任何值属于never,反过来它也"永远装不下"任何值。这正是下面所有行为(不可赋值、穷尽性检查)的根基。
二、三种典型用法:永不返回、抛错与不可达分支
2.1 标注永不返回的函数:无限循环
原文档给出的第一个示例是用never标注"永不返回"的无限循环函数:
const infiniteLoop = (): never => { while (true) { // do something } };由于while (true)永远不会结束,函数不可能正常返回,因此返回类型不能是void(void表示"没有返回值但会返回"),而必须是never。
2.2 标注必然抛错的函数
第二个示例是抛出错误的函数:
const throwError = (message: string): never => { throw new Error(message); };throw语句会中断控制流,函数同样"永不返回",所以返回类型标注为never是准确的。这也是 built-in-type-primitives.md 中对never的官方描述:"Typically used as the return type of functions that throw an error or enter an infinite loop"(典型用于抛错或进入无限循环的函数返回类型)。
2.3 类型收窄后的不可达分支
在 the-never-type.md 中,仓库展示了另一个重要场景:当变量被收窄(narrowing)到"不可能再有任何值"时,编译器会把它推断为never:
const printValue = (val: string | number) => { if (typeof val === 'string') { console.log(val.toUpperCase()); } else if (typeof val === 'number') { console.log(val.toFixed(2)); } else { // val 在这里的类型是 never, // 因为除了 string 或 number,它不可能是其他任何值 const neverVal: never = val; console.log(`Unexpected value: ${neverVal}`); } };这是类型收窄(narrowing)与 control-flow-analysis.md 共同作用的结果:控制流分析会沿着if/else if/else逐步缩小变量的类型域,当所有可能分支都被覆盖后,else分支里的变量类型域成为空集,编译器便将其推断为never。
三、穷尽性检查:让联合类型"增员即报错"
never最有实战价值的用法,是配合switch语句实现穷尽性检查(exhaustiveness checking)。仓库的 exhaustiveness-checking.md 给出了标准范式:
type Direction = 'up' | 'down'; const move = (direction: Direction) => { switch (direction) { case 'up': console.log('Moving up'); break; case 'down': console.log('Moving down'); break; default: const exhaustiveCheck: never = direction; console.log(exhaustiveCheck); // 这一行永远不会被执行 } };这段代码的价值在于可维护性:如果未来有人给Direction增加一个新成员(例如'left'),而switch中没有对应case,那么default分支里direction的类型就不再是never,而是'left'。此时const exhaustiveCheck: never = direction这行赋值会触发编译错误——"Type 'left' is not assignable to type 'never'"——从而在编译期就提醒开发者补全新分支。
这与原文档 never-type.md 中的示例一致(其default分支同样借助const exhaustiveCheck: never = direction;来兜底),二者共同构成了本书对穷尽性检查的完整讲解。
四、区分易混淆类型:nevervsvoidvsunknown
理解never需要把它和相近类型区分开:
| 类型 | 含义 | 典型场景 |
|---|---|---|
never | 空集,值永不出现 | 无限循环、抛错函数、穷尽性检查 |
void | 没有返回值,但函数会正常返回 | 事件处理器、无返回值的函数 |
unknown | 任意值,但使用前必须收窄 | 外部输入、JSON 解析结果 |
any | 任意值,放弃类型检查 | 迁移期兜底(不推荐) |
关于赋值方向的细节,exploring-the-type-system.md 给出了关键事实:
let f: never; f = 1; // Invalid,没有任何东西可以赋给 never即:一切类型都可以赋给any/unknown,但没有任何值可以赋给never(never只可赋给它自身与any)。同时仓库提醒:启用strictNullChecks后,null与undefined的行为类似于void;未启用时,它们的行为则类似于never。
五、延伸阅读
never是本书类型系统章节体系的一部分,建议按以下顺序结合阅读:
- 类型收窄(Narrowing):
typeof、真值判断、switch、in、instanceof等收窄手段,是never推断的前提; - 控制流分析(Control Flow Analysis):理解编译器如何沿分支收窄类型、推断
never; - 穷尽性检查(Exhaustiveness Checking):
never在default分支中的标准用法; - 联合类型(Union Type):
never常与联合类型搭配,构成可穷尽的分支集合; - 探索类型系统(Exploring the Type System):以集合论视角理解
never作为空集的性质。
小结
never虽然"装不下任何值",却在 TypeScript 的类型安全体系中扮演关键角色:它精确标注永不返回的函数,揭示不可达分支,并通过穷尽性检查把"漏掉分支"从运行时 bug 变成编译期错误。掌握never,你就能为联合类型筑牢最后一道防线。
- 文档
- 教程
【免费下载链接】typescript-book
The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.
相关推荐
The Concise TypeScript Book 精读:深入理解 never 类型与穷尽性检查
The Concise TypeScript Book 精读:深入理解 never 类型与穷尽性检查 never 类型是 TypeScript 类型系统中一个看
文档教程The Concise TypeScript Book 精讲:深入理解 `never` 类型与穷尽性检查实战
The Concise TypeScript Book 精讲:深入理解 never 类型与穷尽性检查实战 never 是 TypeScript 内置类型中最特殊
文档教程The Concise TypeScript Book 中的 never 类型:从空集合收窄到穷尽性检查
The Concise TypeScript Book 中的 never 类型:从空集合收窄到穷尽性检查 本篇围绕 The Concise TypeScript
文档教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考