TypeScript 枚举 Enum

JavaScript 本身是没有枚举的,Enum 是 TypeScript 带来的特性。

虽然早在 TypeScript 2.4 就已经提供了 Enum 但是并没有被广泛使用。TypeScript 一开始就有 Union Type,且语法更简单。因此 Enum 在 TypeScript 并不是必需的,出现较晚,且语法更加复杂,阻碍了它的流行。

但是,在大型项目中,Enum 有很多不可替代的优势,结合编辑器和IDE的功能,让类型的使用和维护更加轻松。

和 Union Type 比较

在 Enum 诞生之前,我们经常使用 Union Type 来表示枚举类型:

type Role = 'superadmin' | 'admin' | 'editor' | 'contributor';

const myRole: Role = 'editor';

如果改写成 Enum 的话:

enum Role {
  SuperAdmin = 'superadmin',
  Admin = 'admin',
  Editor = 'editor',
  Contributor = 'contributor',
}

const myRole = Role.Editor;

乍一看是不是代码繁琐了很多?那为什么我们还需要用 Enum 呢?Enum 和 Union Type 相比有两个优点:

  1. 可以对每个枚举成员添加注释
  2. 可以快速且精准地修改值和重命名

项目越大,类型也就会越多,相应的术语也就会越多。对每个枚举值成员添加注释,能够帮助新加入的开发者快速熟悉项目。尤其是国内的项目,中文的项目文档和英文代码之间的联系,注释必不可少。

/** 用户角色 */
enum Role {
  /** 超级管理员,可以增删管理员,配置和删除项目 */
  SuperAdmin = 'superadmin',
  /** 管理员,可以管理除了管理员外的成员角色 */
  Admin = 'admin',
  /** 编辑,可以直接编辑内容 */
  Editor = 'editor',
  /** 贡献者,可以参与讨论和提交补丁 */
  Contributor = 'contributor',
}

const myRole = Role.Editor;

当我们需要修改枚举值时,比如将 superadmin 改为 owner,Enum 就会非常简单。只需要将枚举值更改,而不需要去更改其他引用的地方。然而对于 Union Type,我们要小心翼翼地查找和替换每个出现的地方。加入我们想把 SuperAdmin 替换成 Owner,也只需要用 IDE 和编辑器提供的重命名/重构功能,快速而精确地重命名。这种维护的便利,也是 Enum 最大的魅力。