Any、unknown和never类型

any

any 类型表示没有任何限制,该类型的变量可以赋予任意类型的值

从集合论的角度看,any类型可以看成是所有其他类型的全集,包含了一切可能的类型。TypeScript 将这种类型称为“顶层类型”(top type),意为涵盖了所有下层

1
2
3
4
5
let x:any;

x = 1;
x = "hello";
x = false;

变量类型一旦设为any,TypeScript 实际上会关闭这个变量的类型检查。即使有明显的类型错误,只要句法正确,都不会报错

1
2
3
4
let x:any = 'hello';

x(1) // 不报错
x.foo = 100; // 不报错

由于这个原因,应该尽量避免使用any类型,否则就失去了使用 TypeScript 的意义

实际开发中,any类型主要适用以下两个场合:

  • 出于特殊原因,需要关闭某些变量的类型检查,就可以把该变量的类型设为any
  • 为了适配以前老的 JavaScript 项目,让代码快速迁移到 TypeScript,可以把变量类型设为any。有些年代很久的大型 JavaScript 项目,尤其是别人的代码,很难为每一行适配正确的类型,这时你为那些类型复杂的变量加上any,TypeScript 编译时就不会报错

注意:any 存在污染问题,使用any,将关闭类型检测,所以any可以赋值给其他任何类型

1
2
3
4
5
6
7
let x:any = 'hello';
let y:number;

y = x; // 不报错

y * 123 // 不报错
y.toFixed() // 不报错

unknown

为了解决any类型“污染”其他变量的问题,TypeScript 3.0 引入了unknown类型

它与any含义相同,表示类型不确定,可能是任意类型,但是它的使用有一些限制,不像any那样自由,可以视为严格版的any。

unknown跟any的相似之处,在于所有类型的值都可以分配给unknown类型,但是unknown不能赋值给任何类型,也不能直接调用unknown类型变量的方法和属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
let x:unknown;

x = true; // 正确
x = 42; // 正确
x = 'Hello World'; // 正确

let v:unknown = 123;

let v1:boolean = v; // 报错
let v2:number = v; // 报错

let v1:unknown = { foo: 123 };
v1.foo  // 报错

let v2:unknown = 'hello';
v2.trim() // 报错

let v3:unknown = (n = 0) => n + 1;
v3() // 报错

unknown类型变量能够进行的运算是有限的,只能进行比较运算(运算符==、===、!=、!==、||、&&、?)、取反运算(运算符!)、typeof运算符和instanceof运算符这几种

1
2
3
4
let a:unknown = 1;

a + 1 // 报错
a === 1 // 正确

never

为了保持与集合论的对应关系,以及类型运算的完整性,TypeScript 还引入了“空类型”的概念,即该类型为空,不包含任何值

never变量不能赋值,但是可以赋值给其他任何类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
let xnever; //正确
let a:never = 1; // 报错

let y:number = x; // 报错

function f():never {
  throw new Error('Error');
}

let v1:number = f(); // 正确
let v2:string = f(); // 正确
let v3:boolean = f(); // 正确

总结

any和unknown相同点:

  • 可以赋值任何类型
  • 类型收窄以后可能进行对应类型的操作

any和unknown不同点:

  • unknown 变量不能赋值给其他变量
  • 不能访问 unknown 的属性
  • unknown 的变量只能进行 比较运算(== 、===、!= 、!== )逻辑运算(!、&& 、|| 、?) typeof 和 instanceof,其他运算会报错

顶层类型:(可以承接任何类型)

  • any
  • unknown

底层类型:(可以赋值给任何类型)

  • never

12.91k 字
12篇文章