Never类型

Typescript中有一个叫做never的类型,官网中对它的介绍:

The never type represents the type of values that never occur. For instance, never is the return type for a function expression or an arrow function expression that always throws an exception or one that never returns. Variables also acquire the type never when narrowed by any type guards that can never be true. The never type is a subtype of, and assignable to, every type; however, no type is a subtype of, or assignable to, never (except never itself). Even any isn’t assignable to never.

翻译一下就是:

never类型代表这个值永远不会发生(occur),举个例子,never类型可以用于「总是会抛出错误」/ 「永远不会返回」的函数返回值,变量也可以通过一些type guards(类型保护)来拥有never类型。never类型是任何类型的子类型,可以被赋值给任何类型,但是除了never类型本身,其他类型的值都无法被赋值给never类型。

具体的使用案例就是exhaustiveness checking(穷尽检验):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
function assertNever(x: never): never {
  throw new Error("Unexpected object: " + x);
}
type Type = 'loading' | 'failed' | 'success';

function logger(state: Type): string {
  switch (state) {
    case "loading":
      return "loading request";
    case "failed":
      return "failed with code";
    case "success":
      return "got response";
    default: 
      return assertNever(state)
  }
}

上面代码Type目前只拥有三种状态,如果我们现在突然要增加一个状态idle:

1
type State = 'loading' | 'failed' | 'success' | 'idle';

这个时候Typescript就会提示我们代码报错,因为我们在switch...case中,我们落下了idle这种情况,所以最后idle就会被赋值给never类型,这是不被允许的,只有never类型的变量可以被赋值给never类型的变量,其他类型(在这里是string类型)赋值给never类型都会报错,所以编辑器会报错:

Argument of type 'string' is not assignable to parameter of type 'never'

有了这层保护,代码安全多了,这就是never的作用,这种方式可以叫做bottom type

updatedupdated2020-10-032020-10-03