在TypeScript中,类型any、unknown和object用于不同的场景,并具有关键区别:
any:禁用变量的类型系统。允许对变量进行任何操作,而不引发编译错误。 当对象的类型事先未知且安全性不重要时使用。unknown:同样接受任何类型,但在处理这些变量时需要显式的类型检查/转换。 比any更安全。 使用于类型未知的值,以避免失去对类型的控制。object:仅用于非原始对象(对象、数组、函数),而不用于原始类型(数字、字符串)。 限制仅与对象一起工作。let a: any = 1; a = 'string'; // OK a(); // OK(但可能导致运行时错误) let b: unknown = 'hello'; b = 5; // OK // b.toUpperCase(); // 错误 — 需要类型检查 if (typeof b === 'string') { console.log(b.toUpperCase()); } let c: object = { key: 'value' }; c = [1, 2, 3]; // OK // c = 1; // 错误,因为'1'不是对象
问题: 如果我们可以使用any,unknown有什么好处?
答案: unknown提高了代码的安全性——你不能对变量执行未经检查的操作,就像在any中那样。 需要显式地检查或转换类型,这排除了许多运行时的意外情况。
function handle(value: unknown) { // value.trim(); // 错误 if (typeof value === 'string') { value.trim(); } }
故事
在项目中,决定快速集成第三方库,通过any描述其结果,以免为类型而烦恼。结果在运行时发现,库返回的不是数组,而是具有字段的对象,导致.map()方法频繁出现错误——这段代码编译通过,但在执行时崩溃。
故事
一位开发者使用unknown处理来自后端的数据,但在使用字段之前没有添加类型检查。结果,TypeScript没有编译代码——不得不迅速更改为any,这隐藏了潜在的解析错误,并导致生产环境中的数据格式不正确而出现bug。
故事
在处理object类型时出现了混淆:尝试将string和number值分配给类型为object的变量。 虽然在开发阶段没有发现问题,但在审查过程中发现了与对象的方法不能与原始类型一起工作相关的错误。花费了额外的时间来修复。