TypeScript 的 any、unknown、never 有什么区别?

📅 发布时间:2026/10/14 9:36:32
TypeScript 的 any、unknown、never 有什么区别?
TypeScript 的 any、unknown、never 有什么区别any 允许咱们按需要访问属性、调用方法编译器会放宽相关检查。这在迁移旧代码时有时方便但错误也可能一路传到后面的代码。unknown 同样可以接收各种值但使用前要先判断它是什么。例如确认是字符串以后才能按字符串处理所以更适合还没验证的外部输入。never 表示不会出现正常值的类型常见于不会正常返回的函数或者已经排除所有情况的分支。它可以用来检查联合类型是否已经处理完整。因此接口边界可以先接 unknown运行时确认结构以后再进入业务类型。不要把 as User 当成校验也不要为了省几行判断把所有输入都改成 any。从一份不可信的 JSON 到可以使用的数据标注为 User不会改变收到的数据假设后端返回一份用户信息咱们希望 name 是字符串。请求成功只能说明拿到了响应实际数据里 name 仍可能缺失或者已经改成另一个形态。把结果断言成 User编译器可能同意后续使用但那份数据并没有被检查。因此先把未确认输入保留成 unknown。它会提醒调用方你还需要做一步判断才知道能不能读取这个字段。unknown 让检查成为使用前的条件例如只接受字符串姓名可以直接在边界收窄。functionreadName(value:unknown):string{if(typeofvalue!string){thrownewError(name must be a string);}returnvalue.trim();}console.log(readName( Lin ));// Lin这里的 typeof 真正在运行时执行后续代码又能取得字符串的静态类型。两部分配合才把输入带进可信范围。实际 JSON 是嵌套对象时要逐层检查必要字段或者采用合适的 Schema 工具。不能只检查 typeof value “object”就认定所有内部字段正确因为 null 和数组也需要另外判断。Python 也有自己的静态标注与运行时验证方式但没有同义的 unknown/never 组合语义本题代码限定 TypeScript。any 的问题会沿着数据传下去any 不只是某一行少一次提示。把它传给函数、读出属性或参与表达式以后后面也可能失去有用的检查信息。这不是说 any 永远不能用。迁移第三方代码、处理尚未整理的边界时可以限定一小块范围同时安排实际验证和后续收紧。更需要警惕的是在公共函数返回类型里随意写 any。调用方不知道哪里已经检查、哪里仍然不可信就只能各自猜测。never 能把遗漏分支暴露出来假设任务状态是 queued、running、done。使用 switch 分别处理后默认分支里可以调用一个只接收 never 的函数。当联合类型增加 failed而 switch 没有补处理时默认分支里的值就不再是 never类型检查可以发现遗漏。但这个检查的前提是编译器看到了完整、可信的联合类型。外部 JSON 仍然可能携带未知状态因此边界验证不能省。另外void 通常表达咱们不使用函数的返回值函数仍可以正常结束never 的函数不会正常返回。把它们都理解成“没有返回值”会漏掉这个区别。本题机制参考TypeScript 函数与特殊类型、TypeScript 类型收窄。面试官继续追问unknown 可以直接强制转成 User 吗语法上可以断言但相应的检查责任仍然在咱们身上。断言不是验证证据数据进入业务前要有实际检查。函数抛错误返回类型一定写 never 吗当这个函数在所有执行路径上都不会正常返回时never 才合适。某个分支可能抛错、其他分支正常返回的函数需要描述实际返回值。never 的穷尽检查能防住接口新状态吗它能检查代码里的类型覆盖。服务端直接返回未知状态时首先需要运行时验证与兼容策略不能指望已经编译好的代码自动发现服务端变化。面试速记卡any放宽检查注意传播范围。unknown先检查与收窄再使用。never没有正常值用于不返回路径与穷尽检查。void不使用返回结果不等于不能正常返回。接口边界断言不校验外部值先验证。我是程序员Sunday。本文收录于 sunday面试指南原文与配图可继续阅读。