在 TS 里简单区分 any, unknown, never 的差别

any

任意类型。即不作任何约束,编译时会跳过对其的类型检查。

表现:

  1. 可以被任意值所赋值
  2. 可以赋值给任意定义
  3. 访问一切这个变量下的属性或者方法都不会做检查而报错。

如下列的代码,均不对 test 变量做类型检查。

// 1. 可以被任意值所赋值
let test: any
test = {}
test = 1
test = '123'
test = true

// 2. 可以赋值给任意定义
function add(num1: number, num2: number) {
  return num1 + num2
}
add(test, test)

// 3. 访问一切这个变量下的属性或者方法都不会做检查而报错。
test.a.b = 1

unknown

未知类型,即不知道会得到什么样的数据。TS 3.0 引入。

表现:

  1. 可以被任意值赋值
  2. 只能赋值给 any 和 unknown 类型的值
  3. 不允许执行变量的方法以及访问内部属性
// 1.
let test: unknown
test = {}
test = 1
test = '123'
test = true

// 2.
function add(num1: number, num2: number) {
  return num1 + num2
}
add(test, test) // 报错: 类型“unknown”的参数不能赋给类型“number”的参数。ts(2345)

// 3.
test.a.b = 1 // 报错: 对象的类型为 "unknown"。ts(2571)

never

不存在值的类型。TS 2.0 引入。

通常情况下,一个变量被申明,若是没有特别指定,也会被初始化为 undefined 类型。这种类型就是特意用来标注这个变量,这个函数的返回没有值的,见一个例子

function throwErr (msg: string): never {
  throw new Error(msg)
}

function generateErr(num: number): never {
  if (num > 1) {
    throw new Error()
  }
} // 报错: 返回“从不”的函数不能具有可访问的终结点。ts(2534)

如上的函数恒抛出错误,永远不会有返回值,所以可以定义为 never。而有条件能返回哪怕是 undefined 值的,也不能定义为 never。

表现:

  1. 除了 never 类型外,其他类型均不能给 never 类型的定义赋值。
  2. never 是所有类型的子类型,可以给所有类型赋值,但前提是 tsconfig 里开启 "strictNullChecks": false
  3. 不允许执行变量的方法以及访问内部属性
// 1.
let test: never
test = {} // 报错: 不能将类型“{}”分配给类型“never”。ts(2322)
test = 1 // 报错: 不能将类型“{}”分配给类型“never”。ts(2322)
test = '123' // 报错: 不能将类型“{}”分配给类型“never”。ts(2322)
test = true // 报错: 不能将类型“{}”分配给类型“never”。ts(2322)

// 2.
function add(num1: number, num2: number) {
  return num1 + num2
}
add(test, test)

// 3.
test.a.b = 1 // 报错: 类型“never”上不存在属性“a”。ts(2339)
posted @ 2022-09-28 15:46  Ever-Lose  阅读(1185)  评论(0编辑  收藏  举报