TypeScript 中的 unknown 与 any

说明 unknown 与 any 的根本差异、各自适用场景,以及为什么 unknown 更适合作为不可信输入的默认类型。

#tech / dev #resource / typescript #type / concept #status / growing

[!info] related notes

TypeScript 中的 unknown 与 any

一句话定义

any 会直接绕过类型系统,而 unknown 会保留“这个值还不可信”的信息,要求你在使用前先做类型缩小。

核心机制 / 工作原理

any 在做什么

当一个值被标成 any 时,TypeScript 基本停止对它继续追责。你可以:

  • 访问任意属性
  • 调用任意方法
  • 把它赋给几乎任何别的类型

它更像一种逃生舱。

unknown 在做什么

unknown 也能接收任何值,但在你证明它是什么之前,你不能直接使用它的结构。

这会强迫你先做:

  • typeof
  • instanceof
  • in
  • 自定义类型谓词

最小例子 / 最小场景

any

let value: any = 10;
value.toUpperCase(); // 编译通过,但运行时报错

unknown

let value: unknown = "hello";

if (typeof value === "string") {
  value.toUpperCase();
}

核心区别对照表

特性any (顶级类型)unknown (顶级类型)
可赋值性任何类型都能赋给 any任何类型都能赋给 unknown
操作权限允许访问任何属性、调用任何方法不允许访问属性或调用方法
赋值给他人可以赋值给除 never 外的任何类型只能赋值给 unknownany
安全性极低(绕过类型检查)极高(强制类型检查)

使用场景建议

更推荐 unknown 的场景

  • 外部 API 返回值
  • JSON.parse() 的结果
  • 用户输入
  • 第三方 SDK 给出的未知结构
  • 需要逐步收窄的数据入口

any 还能在哪些场景暂时出现

  • JS 向 TS 迁移初期的过渡区
  • 类型信息确实不存在、又需要先把流程跑通的极小范围
  • 第三方类型极度不完整时的局部兜底

默认原则仍然是:能用 unknown 就不要先上 any

边界与易混淆点

unknown 不是“更麻烦的 any”

它的价值就在于保留“不确定性”,逼你把风险显式处理掉。

as 断言会削弱 unknown 的价值

如果把 unknown 立即断成具体类型,那么它带来的保护会迅速消失。

创建于 2026/2/24 更新于 2026/5/27