typescript中 any、unknown、never类型区别

本文详细解释了TypeScript中的any、unknown和never三种类型的区别,包括any的灵活但存在安全隐患,unknown的更安全限制使用,以及never代表不可能存在的值。强调了它们在类型检查和集合论中的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typescript中 any、unknown、never类型区别

一、any类型

1、any特点和问题:

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

2)对于开发者没有指定类型、TypeScript 必须自己推断类型的那些变量,如果无法推断出类型,TypeScript 就会认为该变量的类型是any,存在安全隐患

3)any类型除了关闭类型检查,还有一个很大的问题,就是它会“污染”其他变量。它可以赋值给其他任何类型的变量(因为没有类型检查),导致其他变量出错。

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

(1)出于特殊原因,需要关闭某些变量的类型检查,就可以把该变量的类型设为any。

(2)为了适配以前老的 JavaScript 项目,让代码快速迁移到 TypeScript,可以把变量类型设为any。有些年代很久的大型 JavaScript 项目,尤其是别人的代码,很难为每一行适配正确的类型,这时你为那些类型复杂的变量加上any,TypeScript 编译时就不会报错。

总之,TypeScript 认为,只要开发者使用了any类型,就表示开发者想要自己来处理这些代码,所以就不对any类型进行任何限制,怎么使用都可以。

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

二、unkonwn类型

为了解决any类型“污染”其他变量的问题,TypeScript 3.0 引入了unknown类型。它与any含义相同,表示类型不确定,可能是任意类型,但是它的使用有一些限制,不像any那样自由,可以视为严格版的any。

unknown 和 any 的 相同和区别:

1、unknown跟any的相似之处,在于所有类型的值都可以分配给unknown类型。

2、unknown类型跟any类型的不同之处在于,它不能直接使用。主要有以下几个限制。

1)首先,unknown类型的变量,不能直接赋值给其他类型的变量(除了any类型和unknown类型)。避免了污染问题,从而克服了any类型的一大缺点。

let v:unknown = 123;

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

2)其次,不能直接调用unknown类型变量的方法和属性。

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

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

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

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

let a:unknown = 1;

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

那么,怎么才能使用unknown类型变量呢?

答案是只有经过“类型缩小”,unknown类型变量才可以使用。所谓“类型缩小”,就是缩小unknown变量的类型范围,确保不会出错。(类型缩小:只有明确unknown变量的实际类型,才允许使用它,防止像any那样可以随意乱用,“污染”其他变量。类型缩小以后再使用,就不会报错)

let s:unknown = 'hello';

if (typeof s === 'string') {
  s.length; // 正确
}

总之,unknown可以看作是更安全的any。一般来说,凡是需要设为any类型的地方,通常都应该优先考虑设为unknown类型。

在集合论上,unknown也可以视为所有其他类型(除了any)的全集,所以它和any一样,也属于 TypeScript 的顶层类型。

三、never 类型

由于不存在任何属于“空类型”的值,所以该类型被称为never,即不可能有这样的值。

let x:never;		
x = 1 // 报错
x = 'hello' // 报错:不可能赋给它任何值,否则都会报错

never 类型的特点

never类型的一个重要特点是,可以赋值给任意其他类型。

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

let v1:number = f(); // 不报错
let v2:string = f(); // 不报错
let v3:boolean = f(); // 不报错

为什么never类型可以赋值给任意其他类型呢?这也跟集合论有关,空集是任何集合的子集。TypeScript 就相应规定,任何类型都包含了never类型。因此,never类型是任何其他类型所共有的,TypeScript 把这种情况称为“底层类型”(bottom type)。

四、总结

总之,TypeScript 有两个“顶层类型”(any和unknown),但是“底层类型”只有never唯一一个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值