nmsn / blog

记录日常遇到的问题,需要记录的笔记以及新学到的知识,会进行汇总和分类,自动更新 README,欢迎评论和补充,互相学习
36 stars 0 forks source link

typescript 中的 any/unknown/void/never #14

Open nmsn opened 2 years ago

nmsn commented 2 years ago

any

任意类型,可取值可赋值,不作任何约束,编译时跳过类型检查,尽量减少使用

any 类型除了会关闭类型检查,还会污染其他变量,导致其他变量出错

unknown

表示未知类型,它能被赋值为任何类型,但不能被赋值给除了 any 和 unknown 之外的其他类型(替换 any 的安全版本)

不能调用 unknown 类型变量的方法和属性

unknown 类型变量能够进行的运算是有限的(运算符==、===、!=、!==、||、&&、?)、取反运算(运算符!)、typeof运算符和instanceof运算符这几种,其他运算都会报错

所以要使用 unkonwn 类型变量需要进行类型缩小

类似于

let a:unknown = 1;

if (typeof a === 'number') {
  let r = a + 10; // 正确
}

上面示例中,unknown类型的变量a经过typeof运算以后,能够确定实际类型是number,就能用于加法运算了。这就是“类型缩小”,即将一个不确定的类型缩小为更明确的类型。

void

表示无任何类型,常用于描述无返回类型的函数

function a():void {
  console.log('message')
}

为变量定义时只能赋值为 undefined/null(配置为 "strictNullChecks": false)/void 没有什么实用价值

never

表示永不存在的值的类型,常用来表示函数报错或者死循环的情况,never 是所有类型的子类型,同时也没有任何类型是 never 的子类型,除了 never 自身

使用场景

1. 表示函数报错或者死循环

function error(message: string): never {
  throw new Error(message);
}

function fail() {
  return error("Something failed");
}

function infiniteLoop(): never {
  while (true) {}
}

2. 可以用在 switch 当中判断 type,用于收窄类型

参考链接:https://www.zhihu.com/question/354601204/answer/888551021

3. 表示类型推断中不会返回的部分

例如 Exclude 中不返回的类型

type Exclude<T, U> = T extends U ? never : T