马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
TypeScript 罗列通过定名常量、类型安全和布局化构造,显著提升代码质量。使用时需根据场景选择符合的类型(数字、字符串或常量罗列),并权衡性能与动态访问需求。掌握其特性和使用的场景,能在复杂项目中有效提升代码的可维护性和结实性。接下来我会通过案例,深入解读Enum。
一、罗列的核心作用
- 替代魔法值 用故意义的名称取代硬编码数字或字符串,减少代码歧义。
- enum StatusCode { Success = 200, NotFound = 404 }
- if (response.status === StatusCode.Success) { ... } // 比直接判断200更清晰
复制代码 - 类型安全 限制变量只能使用罗列成员,编译器会在赋值或比较时查抄类型。
- enum Direction { Up, Down }
- let dir: Direction = Direction.Up; // 正确
- dir = 3; // 错误:不能将数字直接赋值给枚举类型
复制代码 - 构造相干常量 将逻辑关联的常量归类,便于维护和扩展。
- enum LogLevel { Info, Warn, Error }
复制代码 二、罗列的类型与语法
1. 数字罗列(默认)
- 成员默认从 0 开始自增,也可手动赋值。
- 支持反向映射:通过值获取名称(仅数字罗列)。
- enum Direction {
- Up = 1, // 显式赋值
- Down, // 自动递增为2
- Left = 4,
- Right, // 自动递增为5
- }
- console.log(Direction.Down); // 输出: 2
- console.log(Direction[2]); // 输出: "Down"(反向映射)
复制代码 2. 字符串罗列
- 成员必须显式初始化字符串值。
- 无反方向映射,适用于需明确语义的场景。
- enum LogLevel {
- Info = "INFO",
- Warn = "WARN",
- Error = "ERROR"
- }
- console.log(LogLevel.Info); // 输出: "INFO"
复制代码 3. 常量罗列(const enum)
- 编译时被完全内联,无运行时对象。
- 提升性能,但无法反射或动态访问。
- const enum Size { Small, Medium }
- let size = Size.Small; // 编译后:let size = 0;
复制代码 4. 异构罗列(不保举)
- 混淆数字和字符串成员,易引发混乱。
- enum BooleanLikeEnum {
- No = 0,
- Yes = "YES",
- }
复制代码 5. 同名罗列归并
多个同名的 Enum 布局会主动归并。- enum Foo {
- A,
- }
- enum Foo {
- B = 1,
- }
- enum Foo {
- C = 2,
- }
- // 等同于
- enum Foo {
- A,
- B = 1,
- C = 2
- }
复制代码 三、罗列的高级特性
1. 计算成员与常量成员
- 常量成员:值在编译时确定(字面量、其他常量成员引用)。
- 计算成员:值在运行时计算(需显式初始化后续成员)。
- enum FileAccess {
- None, // 常量成员 0
- Read = 1 << 1, // 计算成员 2
- Write = 1 << 2, // 计算成员 4
- ReadWrite = Read | Write, // 计算成员 6
- // 后续成员必须显式初始化
- Execute = 8
- }
复制代码 2. 罗列作为类型
- 限制变量或参数只能为罗列成员值,这是罗列的一个缺点。
- enum UserRole { Admin, Guest }
- function setRole(role: UserRole) { ... }
- setRole(UserRole.Admin); // 正确
- setRole(2); // 错误:类型不符
复制代码 四、罗列的优缺点对比
长处缺点提升代码可读性编译后天生额外代码(非 const enum)编译时类型查抄字符串罗列不支持反向映射支持反向映射(数字罗列)异构罗列易导致逻辑混乱便于统一管理常量动态访问可能绕过类型查抄(数字罗列)五、使用场景
- 优先使用字符串罗列 提高代码自形貌性,避免数字罗列的隐式歧义。
- 性能敏感场景用 const enum 减少天生代码量,但需确保无需动态访问罗列。
- 替代方案考量
- 联合类型:适用于简朴且无需反向映射的场景。
- type LogLevel = 'INFO' | 'WARN' | 'ERROR';
复制代码 - 对象常量:需手动冻结对象防止修改,无类型束缚。
- const LogLevel = { Info: 'INFO' } as const;
复制代码
引用一个例子:Enum 布局比较适合的场景是,成员的值不重要,名字更重要,从而增加代码的可读性和可维护性。- enum Operator {
- ADD,
- DIV,
- MUL,
- SUB
- }
- function compute(
- op:Operator,
- a:number,
- b:number
- ) {
- switch (op) {
- case Operator.ADD:
- return a + b;
- case Operator.DIV:
- return a / b;
- case Operator.MUL:
- return a * b;
- case Operator.SUB:
- return a - b;
- default:
- throw new Error('wrong operator');
- }
- }
- compute(Operator.ADD, 1, 3) // 4
复制代码 上面示例中,Enum 布局Operator的四个成员表示四则运算“加减乘除”。代码根本不需要用到这四个成员的值,只用成员名就够了。
六、示例对比
罗列 vs 联合类型
罗列方案:- enum Theme { Dark = 'dark', Light = 'light' }
- function setTheme(theme: Theme) { ... }
- setTheme(Theme.Dark);
复制代码 联合类型方案:- type Theme = 'dark' | 'light';
- function setTheme(theme: Theme) { ... }
- setTheme('dark');
复制代码 对比:
- 罗列集中管理常量,修改时只需调整罗列定义。
- 联合类型无需天生额外代码,适合简朴场景。
|