TypeScript 中类型 any,void,unknown,never之间的区别


文章出自个人博客 https://knightyun.github.io/2021/04/03/js-ts-type-compare,转载请申明


TypeScript 拓展了 JavaScript 的基本类型与语言特性,为了覆盖类型检查的情景,衍生出了一些额外的类型,其中 any, unknown, void, never 这几个类型所适用的情形容易使人混淆,下面通过举例进行一下区分;

any

这应该是 typescript 中最开始就会接触到的类型,顾名思义:任意类型,这也是 ts 中不写类型申明时的默认类型,即不作任何约束,编译时会跳过对其的类型检查,

let val1: any;
val1 = 'abc';
val1 = 123;
val1 = true;

const arry: any[] = [123, 'abc', true, null];

void

void 表示无任何类型,正好与 any 相反,没有类型,如果是函数则应没有返回值或者返回 undefined,和 C 等语言中的无返回值函数申明类似:

function voidFn(): void {}
function voidFn1(): void { return undefined; }
function voidFn2(): void { return; }

function voidFn3(): void { return 1; } // Error

变量也可以申明为 void 类型,只不过只能给这个变量分配 undefined, nullvoid 类型的值(如果 ts 配置文件中设置了 "strictNullChecks": false,那么分配 null 类型的值也会报错):

let val1: void;
let val2: null = null;
let val3: undefined = undefined;
let val4: void;

val1 = val2; // "strictNullChecks": false 时报错
val1 = val3;
val1 = val4;

unknown

顾名思义,unknown 表示未知类型,是 typescript 3.0 中引入的新类型,即写代码的时候还不清楚会得到怎样的数据类型,如服务器接口返回的数据,JSON.parse() 返回的结果等;该类型相当于 any,可以理解为官网指定的替代 any 类型的安全版本(因为不提倡直接使用 any 类型);

它能被赋值为任何类型,但不能被赋值给除了 anyunknown 之外的其他类型,同时,不允许执行 unknown 类型变量的方法(any 可以),举个例子:

let uk: unknown = 'abc';

uk = 123;
uk = true;
uk.toString(); // Error

let valAny: any = 'abc';
valAny.toString(); // 'abc'

let uk1: unknown = uk;
let uk2: any = uk;
let uk2: string = uk; // Error

never

never 同样顾名思义,表示永不存在的值的类型,是 typescript 2.0 中引入的新类型,概念有点绕,什么情况下变量会永远不存在值呢?因为通常情况下,变量一旦申明了,就会被分配值,即使没有特别指定,也会被初始化为 undefined,同样一个函数即使有个写返回值,也会默认返回 undefined,也不是真正的不存在返回值:

let foo;
console.log(typeof foo); // 'undefined'

function bar() {};
console.log(typeof bar()); // 'undefined'

其实确实有一些情形,值会永不存在,比如,从程序运行的维度讲,如果一个函数执行时抛出了异常,那么这个函数变永远不会有值了(因为抛出异常会直接中断程序运行,这样程序就运行不到返回值那一步了,即具有不可达的终点,也就永不存在返回了):

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

// 有机会到达终点的函数也算存在返回值,编译会报错
function err1(): never { // Error
  if (Math.random() > 0.5) {
     throw new Error('message');
  }
}

还有一种极端情况也比较类似,就是函数中执行无限循环的代码(死循环),这样也同样使得程序永远无法运行到函数返回值那一步,永不存在返回:

function loopForever(): never {
    while (true) {};
}

变量也可以直接申明为 never 类型,让它永不存在值,其实就是意思就是永远不能给它赋值,否则就会报错,这样就可以形成一种保护机制;

let ne: never;

ne = 123; // Error

另外,never 是所有类型的子类型,意思就是它可以赋值给任何类型(前提是配置里 "strictNullChecks": false,否则检查不通过);

let num: number = 123;
let ne: never;

num = ne;

同时也没有任何类型是 never 的子类型,除了 never 自身,即除了 never 任何类型都不能赋值给 never 类型的变量(如果前提是 "strictNullChecks": truenever 也不能赋值给 never);

let ne1: never;
let ne2: never;

ne1 = ne2;

// any 也不能分配给 never
let any1: any = 123;
ne1 = any1; // Error
  • 16
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 好的。 TypeScript 的 `any` 类型表示一个可以是任何类型的值。它可以用于避免类型检查,或者在你还没有确定类型的情况下使用。但是,使用 `any` 类型会放弃 TypeScript 带来的类型检查的所有优势,因此在能使用更精确类型的地方应尽量避免使用 `any`。 TypeScript 的 `unknown` 类型表示一个未知的类型。它比 `any` 类型更加严格,因为在使用前需要进行类型检查。在某些情况下,你可能希望接收一个未知的值,但是又不想使用 `any` 类型,此时就可以使用 `unknown` 类型TypeScript 的 `never` 类型表示永远不会有返回值的函数的返回值类型。它也可以表示永远不会被执行的代码块的类型。例如,当某个函数的所有可能执行路径都会抛出异常时,它的返回值类型就可以是 `never`。 希望这对你有所帮助。 ### 回答2: TypeScript的`any`、`unknown`和`never`是三种特殊的类型。 1. `any`类型表示任何类型的值都可以赋值给它。它相当于取消了类型检查,可以在编写代码时快速推进开发,但也容易引入潜在的类型错误。使用`any`类型时需要慎重,最好在必要情况下使用,例如在需要与非TypeScript代码进行交互或在临时情况下。 2. `unknown`类型TypeScript 3.0引入的一种类型。与`any`相比,`unknown`类型提供了更加安全的动态类型。当我们不确定变量的类型时,可以使用`unknown`类型来保持类型的不确定性。在使用`unknown`类型的值时,我们必须首先进行类型检查或类型断言,以将其转换为更具体的类型。与`any`不同,`unknown`类型不会自动允许我们执行任意操作。这种类型的引入提高了代码的类型安全性,减少了潜在的类型错误。 3. `never`类型表示它永远不会发生的类型,即表示从不返回值的函数的返回类型以及永远无法完成的操作的结果类型。例如,在一个函数抛出了异常,或者存在无限循环。使用`never`类型可以更好地定义某些情况下的函数或操作的返回类型,同时帮助我们避免潜在的逻辑错误。 ### 回答3: TypeScript是一种静态类型的编程语言,它可以在JavaScript的基础上添加静态类型检查和一些其他特性。在TypeScript有三种特殊的类型:any、unknown和never。 any类型表示任意类型,它可以用来表示任何类型的值。使用any类型可以绕开类型检查,编译器不会对any类型的值进行类型检查和推断。any类型的变量可以接受任何类型的值,因此在使用any类型时需要特别小心,因为它可能导致类型错误和运行时错误。 unknown类型也表示任意类型,但它比any类型更严格。当使用unknown类型时,编译器会要求进行类型检查和类型断言,以确保类型安全。unknown类型的变量不能直接赋值给其他类型的变量,必须经过类型断言或类型检查后才能进行赋值。这种类型更适合在编写通用代码或处理动态类型的情况下使用,相比any类型unknown类型提供了更加严格的类型安全。 never类型表示永远不会发生的类型。它通常会用在函数的返回类型,表示该函数永远不会正常返回。例如,一个会抛出异常或进入无限循环的函数的返回类型可以设为never。同时,never类型也可以用来处理不可到达的代码块,例如一个带有无限循环的函数的后续代码块。 总而言之,在TypeScript,any类型unknown类型都表示任意类型,但unknown类型更加严格,并且要求进行类型检查和类型断言。而never类型表示永远不会发生的类型,通常用于函数的返回类型或不可到达的代码块。使用这些类型要谨慎,并且根据实际需求来选择合适的类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑝琦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值