前言

枚举类型用来取值被限定在一定范围内的场景,比如一周7天,分别取不同的颜色.

示例

枚举使用enum来表示.枚举的成员会被赋值为从0开始增长的数字

  1. enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
  2. Days[0];//Sun
  3. Days['Sun']; // 0

事实上,上面的代码被编译为

  1. var Days;
  2. (function (Days) {
  3. Days[Days["Sun"] = 0] = "Sun";
  4. Days[Days["Mon"] = 1] = "Mon";
  5. Days[Days["Tue"] = 2] = "Tue";
  6. Days[Days["Wed"] = 3] = "Wed";
  7. Days[Days["Thu"] = 4] = "Thu";
  8. Days[Days["Fri"] = 5] = "Fri";
  9. Days[Days["Sat"] = 6] = "Sat";
  10. })(Days || (Days = {}));

手动赋值

我们也可以给枚举项进行手动赋值,赋值后Ts会根据枚举项值自动递增加1

  1. enum Days {Sun = 2, Mon = 4, Tue, Wed, Thu, Fri, Sat}
  2. Days[9] //Sat
  3. Days['Sun'] // 2

我们看下编译后的结果

  1. var Days;
  2. (function (Days) {
  3. Days[Days["Sun"] = 2] = "Sun";
  4. Days[Days["Mon"] = 4] = "Mon";
  5. Days[Days["Tue"] = 5] = "Tue";
  6. Days[Days["Wed"] = 6] = "Wed";
  7. Days[Days["Thu"] = 7] = "Thu";
  8. Days[Days["Fri"] = 8] = "Fri";
  9. Days[Days["Sat"] = 9] = "Sat";
  10. })(Days || (Days = {}));

那么,这时候会有这样一个问题,ts会在最后一个值后自动递增,那么就会存在相同值的情况,ts是不会察觉到这一点的,让我们看下这个情况

  1. enum Days {Sun = 2, Mon = 1, Tue, Wed, Thu, Fri, Sat}
  2. Days[2] //Tue
  3. Days['Sun'] // 2
  4. 结论:在赋值后Tue的值也被枚举为2,后面的值会覆盖前面的值,所以结果为Tue

手动赋值的枚举项值可以不是数字,这时候需要使用类型断言来让tsc无视类型检查

  1. enum Days {Sun = 2, Mon = 1, Tue, Wed, Thu, Fri, Sat = <any> 'hello'}
  2. Days['hello'] //Sat
  3. Days['Sat'] //hello

常数项与计算所得项

枚举项有两种形式,常数项和计算所得项,前面看到的都是常数项。下面看下计算所得项的例子

  1. enum Color {Red, Blue, Green = 'green'.length}
  2. -----------------------------------------------------
  3. Color['Green'] //5
  4. Color[5] //Green
  5. Color[2] //undefined

常数枚举

常数枚举是使用const enum定义的枚举类型,常数枚举与普通枚举的区别,他会在编译阶段被删除,并且不能包含计算的成员.

  1. const enum Dire {
  2. blue,
  3. yellow,
  4. red,
  5. black
  6. }
  7. let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];
  8. DireRes // [0,1,2,3]

外部枚举

外部枚举只会用于编译时的检查,使用declare enum来进行定义

  1. declare enum Dire {
  2. blue,
  3. yellow,
  4. red,
  5. black
  6. }
  7. let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];

编译后的结果如下,可以看到declare enum定义的枚举对象在结果中被删除

  1. var DireRes = [0 /* blue */, 1 /* yellow */, 2 /* red */, 3 /* black */];

同时使用declare和const也是可以的。

  1. declare const enum Dire {
  2. blue,
  3. yellow,
  4. red,
  5. black
  6. }
  7. let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];
  8. DireRes //[ 0, 1, 2, 3 ]