掌握TypeScript中的记录:将枚举映射到标签和颜色的简洁方法

64 阅读3分钟

您是否曾经需要在 TypeScript 中为数字枚举显示用户友好的标签、图标或颜色?许多开发人员要么使用 switch 语句,要么使用临时对象——但有一种更简洁、类型安全的方法:Record。

TypeScript 中的 Record 是什么?

简短定义:Record 是一个对象类型,其键为 K 类型,值为 T 类型。
可以将其视为一种类型安全的方法,用于定义从已知键集合到特定值的“映射”。
以下是一个使用联合类型的简单示例:

// Union type of possible roles
type UserRole = "admin" | "user" | "guest";

// Record<UserRole, string> means:
//   - keys must be "admin" | "user" | "guest"
//   - values must be strings
const roles: Record<UserRole, string> = {
  admin: "Administrator",
  user: "Regular User",
  guest: "Guest User",
};

// ✅ Safe lookup
console.log(roles.admin); // "Administrator"

// ❌ Error: TypeScript won’t let you add an unknown key
// roles.superAdmin = "Super Admin";

这可确保您不会忘记密钥,也不会意外添加额外的密钥。

使用带有枚举的记录(真实示例)

联合类型固然很好,但在实际项目中,我们经常使用枚举。假设你的应用中有一个表示付款状态的枚举:

enum PaymentStatus {
  Unpaid = 0,
  Paid = 1,
  Failed = 2,
}

如果要在 UI 中为每个状态显示标签和颜色,最简单的方法就是使用一堆 switch 语句。而 Record 为我们提供了一种更简洁、更安全的方法:

const PaymentStatusMeta: Record<
PaymentStatus, 
{ label: string; color: string }
> = {
  [PaymentStatus.Unpaid]: { label: "Unpaid", color: "orange" },
  [PaymentStatus.Paid]: { label: "Paid", color: "green" },
  [PaymentStatus.Failed]: { label: "Failed", color: "red" },
};

现在,无论您在哪里需要给定状态的元数据:

const status = PaymentStatus.Paid;
console.log(PaymentStatusMeta[status].label); // "Paid"
console.log(PaymentStatusMeta[status].color); // "green"

辅助函数,使用更简洁,
您无需每次都直接访问 PaymentStatusMeta,而是可以将其包装在函数中:

function getPaymentStatusMeta(status: PaymentStatus) {
  return PaymentStatusMeta[status];
}

// Usage
const info = getPaymentStatusMeta(PaymentStatus.Failed);
console.log(info.label); // "Failed"
console.log(info.color); // "red"

这使得代码更具表现力,并且如果您以后需要在函数内部添加逻辑(如本地化或格式化)而无需触及其余代码库,这也会有所帮助。

为什么要使用 Record?(优点)

使用 TypeScript 中的 Record 将枚举(或联合)映射到元数据可带来以下几个好处:

TypeScript 强制执行全面覆盖

  • TypeScript 确保枚举或联合中的每个键都包含在记录中。
  • 忘记一个案例会导致编译时错误,从而防止运行时错误。

强类型安全

  • 记录内的值必须与您指定的类型相匹配。
  • 不再会在需要对象的地方意外分配字符串。

可通过元数据进行扩展

  • 您可以轻松添加www.tymbjy.com更多字段,如图标、工具提示、localeLabel 等。

比 switch/case语句更简洁

  • 您的代码库中不会分散重复的 switch 语句。
  • 查找简单易读:PaymentStatusMeta[status].label

可预测且可维护

  • 未来的开发人员可以立即知道在哪里找到映射。添加新的枚举值只需更新一个位置。

如果您觉得本指南有用:
✅ 请保存以备将来参考。🔁
与你的团队或开发者朋友分享。💬
请在下方评论你最喜欢的 TypeScript 模式,或者你在项目中如何处理枚举元数据。