TypeScript支持数字的和基于字符串的枚举

数字枚举

数字枚举有自增长的行为,默认为数字枚举

  1. enum Direction {
  2. Up = 1, // 如果不写1,默认从0开始递增
  3. Down,
  4. Left,
  5. Right
  6. }

字符串枚举

符串枚举没有自增长的行为

  1. enum Direction {
  2. Up = "UP",
  3. Down = "DOWN",
  4. Left = "LEFT",
  5. Right = "RIGHT",
  6. }

异构枚举

从技术的角度来说,枚举可以混合字符串和数字成员,但不建议这么做

  1. enum BooleanLikeHeterogeneousEnum {
  2. No = 0,
  3. Yes = "YES",
  4. }

手动赋值

如果未手动赋值的枚举项与手动赋值的重复了,TypeScript 是不会察觉到这一点的:

  1. enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
  2. console.log(Days["Sun"] === 3); // true
  3. console.log(Days["Wed"] === 3); // true
  4. console.log(Days[3] === "Sun"); // false
  5. console.log(Days[3] === "Wed"); // true

使用的时候需要注意,最好不要出现这种覆盖的情况
当然,手动赋值的枚举项也可以为小数或负数,此时后续未手动赋值的项的递增步长仍为 1

计算的和常量成员

每个枚举成员都带有一个值,它可以是常量的或者是计算出来的

常量型枚举

  • 它是枚举的第一个成员且没有初始化器,这种情况下它被赋予值0
  • 它不带有初始化器且它之前的枚举成员是一个数字常量。 这种情况下,当前枚举成员的值为它上一个枚举成员的值加1。
  • 枚举成员使用常量枚举表达式初始化。

    计算所得项枚举

    ```typescript enum Color {Red, Green, Blue = “blue”.length};
  1. 但是**如果紧接在计算所得项后面的是未手动赋值的项,那么它就会因为无法获得初始值而报错**
  2. ```typescript
  3. enum Color {Red = "red".length, Green, Blue};
  4. // index.ts(1,33): error TS1061: Enum member must have initializer.
  5. // index.ts(1,40): error TS1061: Enum member must have initializer.

联合枚举与枚举成员的类型

存在一种特殊的非计算的常量枚举成员的子集:字面量枚举成员。 字面量枚举成员是指不带有初始值的常量枚举成员,或者是值被初始化为:

  • 任何字符串字面量
  • 任何数字字面量
  • 应用了一元-符号的数字字面量

当枚举类型中的所有成员都是字面量枚举成员时,该枚举类型成了联合枚举类型
当所有枚举成员都拥有字面量枚举值时,它就带有了一种特殊的语义
枚举成员可以成为类型(联合枚举成员类型)

  1. enum Direction {
  2. Up,
  3. Down,
  4. Left,
  5. Right
  6. }
  7. const up : Direction.Up = Direction.Up

枚举类型本身变成了每个枚举成员的联合 (联合枚举类型)

  1. enum Direction {
  2. Up,
  3. Down,
  4. Left,
  5. Right
  6. }
  7. type UnionDirectionType = Direction.Up Direction.Down | Direction.Left | Direction.Right

运行时的枚举

枚举是在运行时真正存在的对象

function f(obj: { X: number }) {
    return obj.X;
}

// 没问题,因为 'E'包含一个数值型属性'X'。
f(E);

编译时的枚举

尽管一个枚举是在运行时真正存在的对象,但keyof关键字的行为与其作用在对象上时有所不同。应该使用keyof typeof来获取一个表示枚举里所有字符串key的类型

enum LogLevel {
    ERROR, WARN, INFO, DEBUG
}

/**
 * 等同于:
 * type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
 */
type LogLevelStrings = keyof typeof LogLevel;

反向映射

数字枚举成员还具有了反向映射,从枚举值到枚举名字

enum Enum {
    A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"

const枚举

它会在编译阶段被删除,并且不能包含计算成员

外部枚举

用来描述已经存在的枚举类型的形状
外部枚举是使用declare enum定义的枚举类型,declare定义的类型只会用于编译时的检查,编译结果中会被删除
外部枚举与声明语句一样,常出现在声明文件中