Skip to content

前言

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

示例

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

js
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};

Days[0];//Sun
Days['Sun']; // 0

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

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

手动赋值

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

js
enum Days {Sun = 2, Mon = 4, Tue, Wed, Thu, Fri, Sat}

Days[9] //Sat
Days['Sun'] // 2

我们看下编译后的结果

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

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

js
enum Days {Sun = 2, Mon = 1, Tue, Wed, Thu, Fri, Sat}

Days[2] //Tue
Days['Sun'] // 2

结论:在赋值后Tue的值也被枚举为2,后面的值会覆盖前面的值,所以结果为Tue

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

js
enum Days {Sun = 2, Mon = 1, Tue, Wed, Thu, Fri, Sat = <any> 'hello'}

Days['hello'] //Sat
Days['Sat'] //hello

常数项与计算所得项

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

js
enum Color {Red, Blue, Green = 'green'.length}

-----------------------------------------------------
Color['Green'] //5
Color[5] //Green
Color[2] //undefined

常数枚举

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

js
const enum Dire {
    blue,
    yellow,
    red,
    black
}

let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];

DireRes // [0,1,2,3]

外部枚举

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

js
declare enum Dire {
    blue,
    yellow,
    red,
    black
}

let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];

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

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

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

js
declare const enum Dire {
    blue,
    yellow,
    red,
    black
}

let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];

DireRes //[ 0, 1, 2, 3 ]