TypeScript Academy · 课时

unknown 与 any:更安全的选择

了解为什么使用 unknown 前必须先检查类型。

第 3 / 4 课13 个步骤

unknown 与 any:更安全的选择 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。

欢迎

TypeScript 3.0 引入了 `unknown` 类型,将其作为 `any` 的类型安全替代方案。在本课中,您将了解 `unknown` 更安全的原因以及适用场景。

any 带来的问题

使用 `any` 时,TypeScript 会关闭所有检查。您可以调用方法、访问属性,以及不受限制地赋值给有类型的变量——整个过程都没有安全保障。
let val: any = getData();
val.someMethod(); // TypeScript: OK. Runtime: possible crash

认识 unknown

`unknown` 是类型安全的顶层类型。和 `any` 一样,它可以保存任意值;但与 `any` 不同,使用它之前必须先缩小类型。
let val: unknown = getData();
// val.someMethod(); // Error: Object is of type 'unknown'

使用 unknown 前先缩小类型

要使用 `unknown` 值,必须先通过类型检查缩小其类型。之后,TypeScript 才会允许对缩小后的类型执行操作。
let input: unknown = getInput();
if (typeof input === 'string') {
  console.log(input.toUpperCase()); // OK — narrowed to string
}

unknown 不能赋值给具体类型

如果没有检查或断言,就不能将 `unknown` 赋值给具体类型。这会强制您在使用值之前先进行验证。
let x: unknown = 'hello';
// let s: string = x; // Error
let s: string = x as string; // OK with assertion

在捕获块中使用 unknown

在 TypeScript 4.0 及更高版本中,捕获的错误默认类型为 `unknown`。这比过去默认为 `any` 更安全,因为它会强制您检查错误类型。
try {
  doSomething();
} catch (err: unknown) {
  if (err instanceof Error) {
    console.log(err.message); // safe
  }
}

将 unknown 用于外部数据

解析 JSON 或接收接口数据时,应先将其类型标注为 `unknown`,验证后再使用。
const raw: unknown = JSON.parse(text);
if (
  typeof raw === 'object' &&
  raw !== null &&
  'name' in raw
) {
  console.log((raw as any).name);
}

unknown 与类型守卫

自定义类型守卫可以与 `unknown` 完美配合,让您在使用复杂结构前先完成验证。
function isUser(val: unknown): val is { name: string } {
  return typeof val === 'object' && val !== null && 'name' in val;
}

unknown 与 never

`unknown` 是顶层类型——每种类型都可以赋值给它。`never` 是底层类型——没有任何类型可以赋值给它。两者正好相反。
// unknown: anything can be assigned to it
let a: unknown = 42; // OK

// never: nothing can be assigned to it
function fail(): never { throw new Error(); }

如何在 any 与 unknown 之间选择

当接收到类型不确定的数据(JSON、用户输入、外部接口数据)时,请使用 `unknown`。只有在迁移期间或使用没有类型定义的库时,才应将 `any` 作为最后手段。

运行时验证库

Zod、Valibot 和 io-ts 等库与 `unknown` 非常适配。它们会解析并验证数据,从 `unknown` 输入中返回类型明确的值。
import { z } from 'zod';
const UserSchema = z.object({ name: z.string(), age: z.number() });
const user = UserSchema.parse(unknownData); // throws if invalid

快速检查

在 TypeScript 中使用 `unknown` 值之前,必须先做什么?

回顾

`unknown` 是 `any` 的安全替代方案。它接受任意值,但会强制您在使用前缩小类型。对于外部数据、捕获块,以及任何类型确实未知的场景,请使用它。
免费开始

用 AI 导师学习 TypeScript — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
101
课程
352

常见问题解答

「unknown 与 any:更安全的选择」课时是免费的吗?

是的 — 「unknown 与 any:更安全的选择」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。

「unknown 与 any:更安全的选择」这节课中我会学到什么?

了解为什么使用 unknown 前必须先检查类型。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「unknown 与 any:更安全的选择」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 TypeScript Academy 课中编写并运行代码吗?

能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 基本类型:string、number、boolean
  2. any 类型与避免使用它的原因
  3. unknown 与 any:更安全的选择
  4. null、undefined 与严格空值检查
← 返回 TypeScript Academy