TypeScript unknown 和 any 区别
在日常写代码时,很多人会遇到变量类型报错的问题——比如随便定义一个变量,后期想随便赋值给另一个变量,结果编辑器直接飘红。这时候,TypeScript 里的 unknown 和 any 就像两个“万能补丁”,但用错了很容易埋下坑。
先搞懂:什么是“类型的安全边界”
TypeScript 是“带检查的 JavaScript”,它的核心目的是帮你提前发现类型错误。就像你给水杯盖盖子,不能用锅盖盖水杯,也不能用茶杯盖盖水壶——类型就是那个“匹配的盖子”,乱盖就会漏水。any 和 unknown 就是两种“暂时没确定盖子的容器”,但它们的权限差了十万八千里。

先看 any:彻底放飞的“无限制补丁”
any 就像你把容器的盖子全拆了,不管塞什么东西进去、倒出来什么,都没人管。举个生活化的例子:你有个抽屉,贴了个“杂物”标签,里面既能放钥匙、袜子,也能塞个小玩具,拿出来的时候想当钥匙用、想当玩具玩,都不会有人拦你。
用代码说就是:
`typescript
let anything: any = "我是字符串";
// 直接给 number 类型的变量赋值,编辑器不报错
let num: number = anything;
// 还能随便调用不存在的方法,编辑器也不管
anything.nonExistMethod();
`
但这种“无限制”是双刃剑——它会直接把 TypeScript 的类型检查关掉,本来要帮你找的错,反而被它藏起来。比如你把一个字符串的 any 赋值给数字变量,运行时可能才会出现计算错误,属于“看起来省心,实则挖坑”的类型。
再看 unknown:留着锁的“有限制补丁”
unknown 就像你有个上了锁的抽屉,标签写“未知物品”,里面能放任何东西(不管是钥匙、袜子还是玩具),但拿出来用之前,必须先解锁——也就是先确定里面到底是什么。还是用刚才的抽屉例子:你要拿“未知物品”当钥匙开门,得先确认它真的是钥匙;要是想当玩具玩,得先看它是不是玩具,不能直接拿了就用。
代码里的表现完全不一样:
`typescript
let something: unknown = "我是字符串";
// 直接赋值给 number 类型的变量,编辑器直接报错
let num: number = something;
// 必须先确认类型才能用
if (typeof something === "string") {
// 类型确定后,编辑器就会放行,把它当字符串用
console.log(something.length);
}
`
这里的“确认类型”就是“类型缩小”,比如用 typeof、instanceof 判断,或者用类型断言告诉编辑器“我确定这是什么类型”。它既保留了“能放任何东西”的灵活性,又不会关掉类型检查,是“安全的补丁”。
一句话总结:什么时候用哪个?
如果是临时写个小脚本,而且之后不会再维护,用 any 确实快——但只要是要长期维护的项目(比如团队开发、之后要迭代),一定要用 unknown。它既不会像 any 那样毁掉类型检查的价值,又能应付“不确定类型”的情况,相当于“带安全锁的万能盒”,既灵活又靠谱。
举个实际场景的例子:如果是从 API 拿回来的响应数据,你不知道它返回的是对象、数组还是字符串,这时候用 unknown 是对的,拿到数据后先判断类型,再对应处理;要是用 any,随便赋值给别的变量,很容易出现“明明要的是数字,结果拿到的是字符串”的运行时错误。
这样对比下来,你就懂了:any 是“没门的后门”,unknown 是“有门禁的入口”——选对了,才能既灵活又不出错。