编程全栈开发员

TypeScript中的枚举类型是如何工作的,有哪些枚举类型?常量和值计算之间有什么区别?使用枚举时可能会出现哪些陷阱?

用 Hintsage AI 助手通过面试

回答

在TypeScript中,支持两种类型的enum

  • 数字型 (numeric) — 默认值按顺序从0开始分配。
  • 字符串型 (string) — 每个值必须显式指定,并且它是一个字符串。

还存在异构枚举(混合类型),但不推荐使用它们。

示例:

enum Status { Init, Loading, Ready = 5, Error } // Status.Error === 6 enum HttpCode { Ok = 200, NotFound = 404, Internal = 'INTERNAL_ERROR' // 错误!只能是字符串或数字 } enum Direction { Up = 'UP', Down = 'DOWN', }

常量值在编译时计算。如果枚举的值依赖于其他计算或表达式(例如,函数),则这成为计算值(computed member)。只有以前的枚举成员可以用于计算当前成员作为默认值。

重要特性:

  • 数字枚举支持反向映射 enum → 数字 → 字符串名称。
  • 字符串枚举仅支持直接映射(名称 → 值)。
  • 在同一个枚举中混合类型会导致编译错误。

设问陷阱

是否可以在声明新的枚举成员时使用另一个枚举的值?

回答: 可以,但前提是这个值是常量或之前声明的成员。

示例:

enum A { X = 1 } enum B { Y = A.X } // 可以

然而,不能使用基于函数的计算或来自其他地方的数据(例如,函数调用)。

由于对主题细微之处的不熟悉而导致的实际错误示例。


故事

在将数据序列化到外部API的项目中,使用了数字枚举。由于枚举成员的顺序发生变化,导致值"漂移",外部系统开始接收到其他数字。这在外部客户端上引发了无法追踪的错误状态,没有代码审计几乎无法发现。


故事

在一个React项目中,错误地在switch-case中使用了字符串和数字枚举,期望值可以转换为字符串。由于不匹配,switch未能正确触发,组件返回了无效的UI。


故事

在尝试创建一个部分值通过函数计算的枚举时,TypeScript没有报错,但在某些构建中值结果为undefined。这导致在枚举用作路径标识符时路由出现问题。这个致命错误仅在生产捆绑包中复现。