首页 TypeScript TypeScript any 和 unknown 的区别

TypeScript any 和 unknown 的区别

0 1.7K

原文地址:https://levelup.gitconnected.com/typescript-difference-between-any-and-unknown-types-1fff4bf232a

我们知道,TypeScript 定义了很多基本数据类型:

  • boolean: true或者false
  • number: 所有数字类型
  • string: 字符串类型,使用引号包围,例如'TypeScript is Awesome'
  • any: 禁用类型检查,允许使用任意类型
  • unknown: 类似any但更安全
  • never: 在使用定义时会抛出一个错误

或许你会对上面描述的anyunknown有疑问。这篇文章就是为了解答你的疑问的。

anyunknown有两个主要区别:

TypeScript 强制要求在使用unknown之前必须确定其具体类型,而any不需要。

例如,

let anyValue: any = 1;
let unknownValue: unknown = 1;

anyValue.helloworld(); // 没有错误
unknownValue.helloWorld(); // TypeScript 错误

不能把unknown赋值给除自己或者any类型以外的其它变量,而any可以赋值给任意变量。

例如,

let anyValue: any = 1;
let unknownValue: unknown = 1;

let str: string;
str = anyValue; // 没有错误
str = unknownValue; // TypeScript 错误

正如上面描述的那样,这些约束确保在使用unknown类型之前,必须进行验证。这对减少运行时错误有重要意义。

下面我们看一些用例。

对未知值进行建模

我们可以使用unknown类型描述未知的值。例如,从网络请求返回的值:

let data: unknown = getSomeValueFromSomeWhere();

if (typeof data === 'string') {
   //data is a string.
} else if (Array.isArray(data)) {
   //data is an array.
} else if (typeof data === 'object') {
   //data is an object.
}

类型断言

在 TypeScript 中,类型断言用于告知编译器一个变量的类型。类型断言类似类型转换,但不需要改造代码。我们通过类型断言告诉编译器变量的类型,从而不需要编译器自己推断类型。但是,我们不能简单地断定一个值可以是我们需要的任意类型。我们不能断言一个值是不匹配其实际值的类型。

例如,

let value = '1' as number; // 错误,我们不能说 string 是 number 类型的

interface Vehicle {
  name: string;
  model: string;
}

function buyVehicle(vehicle: Vehicle){}
buyVehicle({niceVehicle: ''} as Vehicle); // 错误,这个对象没有 Vehicle 所要求的必备字段

一个变通方案是,在将一个值转换成某个与实际不匹配的类型时,现将这个值转换成unknown类型:

buyVehicle({niceVehicle: ''} as unknown as Vehicle)

当然,我们不应该写这样的代码,因为这很容易带来运行时错误。

总结一下,anyunknown类型都是 TypeScript 的基本类型。它们是很相似,但也有一些不同。

any可以很容易绕过类型错误,因为它实际禁止了类型检查,但这么一来,TypeScript 也就不能保证类型安全,同时,所有依赖于类型的工具,比如自动补全,都不能正常工作。

当我们不知道数据的类型时,unknown往往是最好的选择。在后面使用时,我们需要进行类型转换。

提醒一点,我们应该尽可能地少用any

发表评论

关于我

devbean

devbean

豆子,生于山东,定居南京。毕业于山东大学软件工程专业。软件工程师,主要关注于 Qt、Angular 等界面技术。

主题 Salodad 由 PenciDesign 提供 | 静态文件存储由又拍云存储提供 | 苏ICP备13027999号-2