0Pricing
TypeScript Academy · 课时

构建可辨识联合

为联合成员添加共享的辨识属性。

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

什么是可辨识联合

可辨识联合是由多个对象类型组成的联合类型,这些对象类型都共享一个名为判别属性的字面量属性。这个共享标签让 TypeScript 能够区分各个成员。

// The shared "kind" property is the discriminant
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Shape = Circle | Square;

判别属性

判别属性必须是字面量类型(例如 "circle"),而不能是 string 这样的宽泛类型。每个成员都拥有自己唯一的字面量值。

type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };

const c: Circle = { kind: "circle", radius: 10 };
console.log(c.kind); // "circle"

每个成员都有自己的字段

除了共享的判别属性之外,每个成员还包含只有自身才有意义的字段。圆形有 radius,正方形有 side。

type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Rectangle = { kind: "rectangle"; width: number; height: number };
type Shape = Circle | Square | Rectangle;

构造联合类型值

构造值时,TypeScript 会根据其 kind 检查其形状是否与联合类型中的某一个成员完全匹配。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const shapes: Shape[] = [
  { kind: "circle", radius: 5 },
  { kind: "square", side: 4 }
];
console.log(shapes.length); // 2

为什么不只使用可选字段

带有可选字段的宽松类型(radius?、side?)会允许无效组合。可辨识联合可以让非法状态无法表示。

// Loose and error-prone: nothing stops radius + side together
type BadShape = { radius?: number; side?: number };
const bad: BadShape = { radius: 5, side: 4 }; // nonsense, but allowed

判别属性的名称由您决定

这个标签通常称为 kind 或 type,但只要每个成员使用相同的属性名,并且具有不同的字面量值,使用任何名称都可以。

type Event =
  | { type: "click"; x: number; y: number }
  | { type: "scroll"; delta: number };

const e: Event = { type: "click", x: 10, y: 20 };
console.log(e.type); // "click"

建模图形面积计算器

当每个变体需要不同的处理方式时,可辨识联合就能发挥优势。这里我们先设置图形,稍后由面积函数处理它们。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const myShapes: Shape[] = [
  { kind: "circle", radius: 3 },
  { kind: "square", side: 6 }
];
console.log("Count:", myShapes.length);

添加第三个变体

联合类型可以扩展。添加一个 triangle 成员只需修改一行,TypeScript 会在联合类型的所有使用位置跟踪这一变化。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number }
  | { kind: "triangle"; base: number; height: number };

const t: Shape = { kind: "triangle", base: 4, height: 8 };
console.log(t.kind);

唯一字面量可避免重叠

由于每个 kind 都是唯一的,因此不会产生歧义。一个值只能是一个成员,不可能同时属于两个成员。

type A = { kind: "a"; value: number };
type B = { kind: "b"; label: string };
type Union = A | B;

function describe(u: Union) {
  return u.kind === "a" ? u.value : u.label;
}
console.log(describe({ kind: "b", label: "hi" }));

使用布尔标签作为判别属性

判别属性不一定要是字符串。布尔字面量同样适用,这对于表示成功或失败的结果很方便。

type Result =
  | { ok: true; data: string }
  | { ok: false; error: string };

const r: Result = { ok: true, data: "loaded" };
console.log(r.ok ? r.data : r.error);

实际使用可辨识联合

现在您已经拥有了完整的图形模型。在下一课中,我们将根据判别属性进行类型收窄,以安全地访问每个成员的特有字段。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const sample: Shape = { kind: "circle", radius: 7 };
console.log(sample.kind, "ready");

快速检查:判别属性

测试您对可辨识联合的理解。

回顾:构建可辨识联合

您已经了解到,可辨识联合会将共享字面量判别属性(例如 kind)的对象类型组合起来。每个成员都携带自己的字段,唯一的字面量可以避免重叠,而这种模式能让非法状态无法表示。

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const done: Shape = { kind: "square", side: 2 };
console.log("Recap complete:", done.kind);

常见问题解答

「构建可辨识联合」课时是免费的吗?

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

「构建可辨识联合」这节课中我会学到什么?

为联合成员添加共享的辨识属性。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

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

「构建可辨识联合」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 构建可辨识联合
  2. 根据辨识属性进行收窄
  3. 使用 never 进行穷尽性检查
  4. 状态机建模
← 返回 TypeScript Academy