TypeScript Academy · 课时

品牌类型/不透明类型,防止单位混用

通过将基础类型与虚拟品牌属性进行交集运算来避免单位或标签混用;只能通过工厂函数构造这些类型。

第 1 / 3 课8 个步骤

品牌类型/不透明类型,防止单位混用 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 1 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 3 节课。

简介

目标:在类型层面区分外观相似的值。普通的 number 无法区分米和秒;而品牌标记可以做到。

  • 零运行时开销
  • 更安全的应用程序接口和重构
  • 只能通过工厂创建

为基本单位添加品牌

品牌标记会在编译时区分单位;错误的参数顺序会在类型检查时失败。

type Meter = number & { readonly __brand: "meter" }
type Second = number & { readonly __brand: "second" }

function meter(n: number): Meter { return n as Meter }
function second(n: number): Second { return n as Second }

const d = meter(100)
const t = second(9)

function speed(dist: Meter, time: Second) { return (dist as number) / (time as number) }

// speed(t, d)  // compile error: brands do not match

通用品牌辅助函数

在不同领域中使用通用的 Brand 辅助函数:带类型的 ID、令牌、游标等。

type Brand<Tag extends string, T> = T & { readonly __brand: Tag }

type UserId = Brand<"UserId", string>
type OrderId = Brand<"OrderId", string>

function userId(x: string): UserId { return x as UserId }
function orderId(x: string): OrderId { return x as OrderId }

function findUser(id: UserId) { /* ... */ }

const u = userId("u_123")
const o = orderId("o_456")
// findUser(o) // error: OrderId not assignable to UserId

唯一符号品牌标记

唯一符号品牌标记可避免名称冲突,也可防止泄漏到全局命名空间。

declare const MeterSym: unique symbol

type Meter2 = number & { readonly [MeterSym]: "meter" }

function asMeter2(n: number): Meter2 { return n as Meter2 }

const m2 = asMeter2(5)
// const wrong: Meter2 = 5  // discourage raw assignment; prefer factories

工厂与验证

将品牌标记放在工厂中:先验证,再添加品牌标记,最后使用。避免在调用处随意使用 as。

type NonEmptyString = string & { readonly __brand: "NonEmpty" }

function nonEmpty(s: string): NonEmptyString | null {
  return s.trim().length > 0 ? (s as NonEmptyString) : null
}

function makeSlug(s: NonEmptyString) {
  return (s as string).toLowerCase().replace(/\s+/g, "-")
}

const ok = nonEmpty(" Hello ")
if (ok) { makeSlug(ok) }  // safe: validated & branded first

提示与易错点

最佳实践:

  • 品牌名称应简短且有意义。
  • 将工厂作为获取品牌值的唯一途径。
  • 除非必要,不要在公共 API 类型中暴露品牌标记。
  • 品牌标记只存在于类型层面:不会产生运行时开销。

品牌标记检查

快速检查:哪种模式可以防止单位和标签混淆?

回顾

回顾:品牌类型和不透明类型可以区分外观相似的值(米与秒、UserId 与 OrderId)。请通过工厂创建这些值,在各个 API 中使用它们,从而消除意外混淆。

免费开始

用 AI 导师学习 TypeScript — 免费

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

课程
101
课程
352

常见问题解答

「品牌类型/不透明类型,防止单位混用」课时是免费的吗?

是的 — 「品牌类型/不透明类型,防止单位混用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 3 节课。

「品牌类型/不透明类型,防止单位混用」这节课中我会学到什么?

通过将基础类型与虚拟品牌属性进行交集运算来避免单位或标签混用;只能通过工厂函数构造这些类型。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

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

「品牌类型/不透明类型,防止单位混用」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 品牌类型/不透明类型,防止单位混用
  2. 带标签的 ID 与领域建模模式
  3. 领域建模——聚合、不变量与服务
← 返回 TypeScript Academy