TypeScript 的 never 类型

5,852 阅读1分钟

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 Errorreturn 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> 看他们的源码就知道什么意思)。