likes
comments
collection
share

在TS 中 any, never,unknown,和 void 的区别是什么?

作者站长头像
站长
· 阅读数 27

在TS 中 any, never,unknown,和 void 的区别是什么?

作为 JS 的超集,TS 给我们带来了方便的同时,也带来了一些学习成本,本章的目的是了解any, never,unknown,和 void 的区别。

定义

Any

  • 不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any类型来标记这些变量
  • 允许你在编译时可选择地包含或移除类型检查

举个🌰:

let test: any = 4;
test = "maybe a string instead";
test = false;

这里 test 的类型从 number - string - boolean,却没有报错就证明了这一点也恰恰证明了 any 的万金油程度

Void

某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。

(如果有学过 C、Java 的同学可能就很容易理解)(在java中,void代表的意思是 ,即'什么都不返回',在方法申明的时候表示该方法没有返回值。)

举个🌰:

function hello(): void {
    console.log("hello world");
}

聊个课外的话题

如果你想皮一下,把一个变量赋值成 void,当然也是可以的,但是 赋值只能是 null or undefined

const test: void = undefined // 没问题
const test1: void = null // 没问题
const test2: void = 1 // Type '1' is not assignable to type 'void'.

Never

Never 很直观的就告诉我们了:表示的是那些永不存在的值的类型。

引用官方的一句话:

never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。

举个🌰:

function demo1(): never {
    throw new Error('返回never的函数必须存在无法达到的终点');
}

function demo2(): never {
    return error('推断的返回值类型为never');
}

当然 有趣的是:

never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。

Unknown

  • 表示未知类型,即写代码的时候还不知道具体会是怎样的数据类型
  • 与 any 一样,所有类型都可以分配给unknown。 这里可能就有宝子要问了,既然一样,那么为什么还需要出这个类型呢?

这个我们下面来具体说

先举个🌰:

所有类型都可以分配给unknown

let test: unknown = 'Hello'!;
test = 12;
test = { hello: () => 'Hello!' };

但是 unknown 类型的变量只能赋值给 any 和 unknown

let test: unknown = 'Hello'!;
let test2: unknown = test;
let test3: number = test; // 报错

区别

说了这么多,他们的区别到底在哪里?

  • any 和 unknown 在分配类型上是一样的,所有类型都可以分配给他们, 不同的就是unknown不能赋值给 除了unknown 和 any 之外的类型,但是any作为万金油一哥 是没有任何问题的。
    let unknown1: unknown = 1 (可以赋值为任意值)
    let test: string = unknown1 // 报错
    
    let any1: any = 1 (可以赋值为任意值)
    let test2: string = any1 // 不报错
    
  • unknown 和 never就像两个相反的镜像
    • 任意类型都可以赋值给 unknown1; never可以赋值给任意类型的值
    • 没有任何值可以赋值给 never, unknown 不能赋值给任何值(除了any)

拷贝一个官网的表格:

下表总结了一些抽象类型之间的可分配性。 行表示这个类型可以被赋值为的类型: let demo: void = null 列这个类型可以赋值给那些类型:let demo: void = null; 任何赋值给let test: unknown = void

anyunknownobjectvoidundefinednullnever
any →
unknown →
object →
void →
undefined →
null →
never →