在 TS2.0 推出的 never 类型后,让 type 类型的操作,更加灵活。
与 void 的区别
通常情况下我们会这样定义无返回值的函数:
fun: () => void;
但在 TS 中 void
至少包含了以下几个子类型:
- undefined
- null
例如下面的实例:
// strictNullChecks = false 时
const v: void // 等同于 undefined | null
// strictNullChecks = true 时
const v: void // 等同于 undefined
完全无返回值
而 never 是完全没有返回值的类型,只有一种情况会如此:代码阻断。
那么当执行 throw new Error
、 return process.exit(1)
、while(true){}
时都满足此条件:
function error(message: string): never {
throw new Error(message);
}
如果函数的返回值类型是 never
意味的此函数必须不能被顺利完整执行,而发生中断行为。
所有类型的子类型
never 是所有类型的子类型,因此可以理解为:所有的函数的返回值都包含 never 类型:
function fun(s: string): number {
if (s == 'a') return 1;
if (s == 'b') return 2;
throw new Error;
}
// 等同于 fun(s: string): number | never
只要不是单独申明为 never 类型,都会被显性的展示起来,因此下面的声明中也会忽略 never:
type Temp = 1 | 'a' | never
// 得到
// type Temp = 1 | 'a'
Type ne = never
// 得到
// type ne = never
用在函数类型时
之前我们讲解 TypeScript 的 extends 条件类型 时,封装 Filter<T, U>
函数类型就用到了 never 类型的返回值的特性:
type Filter<T, U> = T extends U ? never : T;
type Values = Filter<"x" | "y" | "z", "x">;
// 得到 type Values = "y" | "z"
理解这些类型后,之后理解官方预定于的高级类型,将非常轻松(例如:Exclude<T, U>
、Extract<T, U>
、NonNullable<T>
看他们的源码就知道什么意思)。