TypeScript 中 unknown 与 any 的核心区别解析
本文深入解析 TypeScript 中 unknown 与 any 类型的区别。any 类型允许赋值任意值并执行任意操作,但会丧失类型保护;unknown 类型同样接受任意值,但在使用前必须进行类型检查或断言。通过代码示例对比,说明为何在需要类型安全的场景下应优先使用 unknown 而非 any。
前言
在 TypeScript 中,any 类型的变量可以接收并赋值任何类型的数据。
let myVar: any = 0;
myVar = '1';
myVar = false;
TypeScript 官方指南并不推荐使用 any,因为使用它会放弃类型系统的约束。而引入 TypeScript 的初衷正是为了获得类型约束,因此过度使用 any 与这一初衷相悖。
从 TypeScript 3.0 版本开始,引入了一个与 any 类似但更安全的特殊类型:unknown。对于 unknown 类型的变量,同样可以赋值任何类型的值。
let myVar: unknown = 0;
myVar = '1';
myVar = false;
那么,any 和 unknown 究竟存在哪些具体区别?
1. unknown 与 any 的对比
为了更直观地理解两者的差异,我们先构建一个接收单一参数并尝试调用它的函数。
假设我们将 invokeAnything 函数的参数类型定义为 any。
function invokeAnything(callback: any) {
callback();
}
invokeAnything(1); // throws "TypeError: callback is not a function"
由于 callback 参数被声明为 any 类型,直接调用 callback() 不会触发编译时的类型错误。这意味着使用 any 类型的变量可以执行任意操作。
然而,如果传入非函数类型的值(如数字 1),运行时会抛出 TypeError: callback is not a function。TypeScript 的编译器无法阻止此类运行时错误的发生。
如果既希望 invokeAnything 函数能接受任意类型的参数,又希望强制对参数进行类型检查以避免上述运行时错误,该如何实现?
这时,unknown 类型便派上了用场。
与 any 类似,unknown 类型的变量可以接收任何值。但在尝试使用 unknown 变量时,TypeScript 会强制进行类型检查。这正是我们期望的安全机制。
function invokeAnything(callback: unknown) {
callback();
// Object is of type 'unknown'
}
invokeAnything(1);
当 callback 参数类型为 unknown 时,直接调用 callback() 会引发类型错误:Object is of type 'unknown'。与 any 不同,TypeScript 通过这种方式保护代码,防止调用可能不是函数的对象。
在使用 unknown 类型的变量之前,必须执行类型检查。在示例中,我们需要验证 callback 是否为函数类型。
function invokeAnything(callback: unknown) {
if (typeof callback === 'function') {
callback();
}
}
invokeAnything(1);
2. unknown 和 any 的心智模型
在学习初期,理解 unknown 可能具有一定挑战性,因为它与 any 一样都接受任何值。以下是帮助区分两者的核心规则:
- 可以将任意值赋给 unknown 类型,但在进行类型检查或类型断言之前,不能对 unknown 类型的变量执行操作。
- 可以将任意值赋给 any 类型,并且可以对 any 类型的变量执行任意操作。
上述示例清晰地展示了 unknown 和 any 之间的相似性与不同点。
unknown 示例:
function invokeAnything(callback: unknown) {
// 可以将任何东西赋给 `unknown` 类型,
// 但在进行类型检查或类型断言之前,不能对 `unknown` 进行操作
if (typeof callback === 'function') {
callback();
}
}
invokeAnything(1); // You can assign anything to `unknown` type
通过 typeof callback === 'function' 进行类型检查,确认 callback 是函数后,方可调用。
any 示例:
function invokeAnything(callback: any) {
// 可以对 `any` 类型执行任何操作
callback();
}
invokeAnything(1); // 可以把任何东西分配给`any`类型
如果 callback 是 any 类型,TypeScript 不会强制对 callback() 调用语句进行任何类型检查。
3.总结
unknown 和 any 是两种特殊的类型,它们都能容纳任何值。
推荐使用 unknown 替代 any,因为它提供了更安全的类型约束。如果需要对 unknown 类型的变量进行操作,必须先使用类型断言或将其缩小(narrow)到特定类型。
~~ 完,我是小智,女票在教培行业工作,最近发的工资有点低,我准备多多下海工作,赚更多的钱了。
编辑中可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:dmitripvlutin.com/typescript-…
总结
到此这篇关于TypeScript中unknown与any区别的文章就介绍到这了,更多相关TypeScript unknown与any区别内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18








