https://www.xiangshu233.cn/ts 中的 never 类型另一个妙用/

Never

在 TypeScript 中,never 本质就是一个空集。事实上,在另一个流行的 JavaScript 类型系统 Flow 中,作用完全一样的类型直接被命名为 empty

由于集合中没有值,never 类型字面意义地永远不会(双关)有任何值,包括 any 类型的也不在 never 这个空集中。这就是为什么 never 有时也被称为 uninhabited 类型或 Bottom 类型。

Bottom 类型是 TypeScript 手册 对它的定义。当我们把 never 放一个完整类型层次的树形结构图之后,看起来才比较有意义。

就像在数学中我们使用来表示没有的数量一样,我们需要一个类型来表示类型系统中的不可能

如何使用 never 类型

案例:限制函数参数类型

由于我们永远无法给一个 never 类型赋值,因此我们可以使用它来对函数参数施加限制。

比如这个 log 函数的参数,他可以赋值任何类型,但是唯独不能赋值日期类型

// x 可以是任何类型,但不能是日期
function log(x) {
  console.log(x);
}

第一时间想到的是,我们可以写一个判断,如果 x 是类型日期就抛出一个错误

function log(x) {
  if (x instanceof Date) {
    throw new Error('x 不能是日期类型');
  }
  console.log(x);
}

但是你这样子做,也没毛病,就是用一点也不 TS,你把这个错误的发生事件延迟到了运行时,也就意味着你在编写代码的时候,在运行之前你是收不到任何的错误提示的

可以看到上图中 TS 是不会报错的,只有当你运行了代码的时候你才发现这个错误发生了

那么我们能不能运用 TS 的能力把这个错误提前到编译时呢?答案是当然可以,这就是 TS 的主要功能之一

现在我们把这个判断去掉,给 log 加上一个泛型 T,有了这个泛型参数 T 之后,我们可以对这个参数 x 进行进一步的约束,我们可以使用一个三目运算,看一下这个类型 T 是不是日期,如果说他是日期类型的话,那么这个 x 的类型就给他标注为 never 类型,就是绝不可能的类型,否则的话就是参数 T