发布于2026-07-23 阅读(0)
扫一扫,手机访问
在 TypeScript 的类型系统里,never 绝对算得上一个“特立独行”的存在——它代表的是“永不存在的值类型”。简单说,就是那些根本不可能有结果的情况,比如抛异常的函数、无限循环,或者是在类型收窄时逻辑上永远走不到的分支。下面咱们就好好聊聊它的用法、妙处,以及一些容易踩坑的地方。
第一,抛出异常的函数。 当函数执行到一半直接 throw 一个错误,程序就此终止,不会再返回任何值,这时候返回类型就该写成 never。
function throwError(message: string): never {
throw new Error(message);
}
第二,死循环的函数。 比如一个永远跑不停的 while(true),它永远不会结束,自然也不会返回——never 正好适合它。
function infiniteLoop(): never {
while (true) {}
}
第三,类型保护中的穷尽检查。 在类型缩小(type narrowing)的过程中,用 never 来标记那些理论上不可能出现的分支,能帮我们捕捉遗漏的情况,让代码更严谨。
function handleValue(value: string | number) {
if (typeof value === 'string') {
console.log('String value');
} else if (typeof value === 'number') {
console.log('Number value');
} else {
// 如果 value 类型是 never,编译器会检查这里的情况是否可能发生
const _exhaustiveCheck: never = value;
throw new Error('Unexpected type: ' + value);
}
}
handleValue('string');
handleValue(1);
handleValue(true);

1. 确保类型全面覆盖。 在处理 switch 或多类型分支时,never 可以作为一个“强制检查工具”——如果你漏掉了某个分支,TypeScript 会在编译时报错。举个例子,有一个表示用户状态的联合类型:
type UserStatus = "active" | "inactive" | "banned";
function handleUserStatus(status: UserStatus) {
switch (status) {
case "active":
console.log("User is active");
break;
case "inactive":
console.log("User is inactive");
break;
case "banned":
console.log("User is banned");
break;
default:
// 强制类型检查是否已全面覆盖所有情况
const exhaustiveCheck: never = status;
throw new Error(`Unhandled status: ${status}`);
}
}
关键就在 default 分支里:我们把 status 赋值给一个 never 类型的变量。如果后续 UserStatus 新增了一个成员(比如 'suspended'),而 switch 没处理它,TypeScript 就会报错——因为此时 status 不再是 never,而变成了 'suspended',赋值操作不通过。
type UserStatus = 'active' | 'inactive' | 'banned' | 'suspended';

这样一来,只要有人新增了类型成员,编译器就会立刻提醒你“该补全分支了”,代码健壮性自然就上去了。
2. 类型收窄的辅助。 never 还能帮 TypeScript 判断哪些代码路径永远无法到达,从而优化类型检查和代码推理。比如可以用它来定义一个“排除某类型”的工具:
type MyExclude= T extends U ? never : T; function isNumber (x: MyExclude ) {} isNumber('123') // ok isNumber({}) // ok isNumber(true) // ok isNumber(111) // 报错,因为 111 被 exclude 掉了
这里有一个容易让人困惑的点:直接用条件类型判断 never 时,得到的结果往往不是你想要的。比如 T extends never ? true : false,当 T 是 never 时,结果竟然是 never 而不是 true。
为什么? 因为条件类型具有“分配式”(distributive)特性——当 T 是联合类型时,TypeScript 会把联合的每个成员分别代入条件。而 never 实际上是一个“空的联合类型”,没有成员,所以分配过程无法进行,直接返回 never。
怎么解决? 把 T 包在元组里,阻止分配式行为:
type IsNever= [T] extends [never] ? true : false;
这样 T 会作为一个整体参与判断,never 就能正确返回 true 了:
type Test1 = IsNever; // true type Test2 = IsNever ; // false type Test3 = IsNever ; // false type Test4 = IsNever ; // false
使用 never 时,有几个关键点需要留意:
undefined),用 void 更妥当。void。 void 表示函数没有返回值,但调用后仍会得到 undefined;而 never 表示函数根本不会正常结束——要么抛异常,要么永远运行。never 能帮助 TypeScript 识别和优化代码路径。如果某个分支逻辑没有覆盖全,编译器会主动提醒你,防患于未然。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8