前言
枚举类型用来取值被限定在一定范围内的场景,比如一周7天,分别取不同的颜色.
示例
枚举使用enum来表示.枚举的成员会被赋值为从0开始增长的数字
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};Days[0];//SunDays['Sun']; // 0
事实上,上面的代码被编译为
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
enum Days {Sun = 2, Mon = 4, Tue, Wed, Thu, Fri, Sat}Days[9] //SatDays['Sun'] // 2
我们看下编译后的结果
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是不会察觉到这一点的,让我们看下这个情况
enum Days {Sun = 2, Mon = 1, Tue, Wed, Thu, Fri, Sat}Days[2] //TueDays['Sun'] // 2结论:在赋值后Tue的值也被枚举为2,后面的值会覆盖前面的值,所以结果为Tue
手动赋值的枚举项值可以不是数字,这时候需要使用类型断言来让tsc无视类型检查
enum Days {Sun = 2, Mon = 1, Tue, Wed, Thu, Fri, Sat = <any> 'hello'}Days['hello'] //SatDays['Sat'] //hello
常数项与计算所得项
枚举项有两种形式,常数项和计算所得项,前面看到的都是常数项。下面看下计算所得项的例子
enum Color {Red, Blue, Green = 'green'.length}-----------------------------------------------------Color['Green'] //5Color[5] //GreenColor[2] //undefined
常数枚举
常数枚举是使用const enum定义的枚举类型,常数枚举与普通枚举的区别,他会在编译阶段被删除,并且不能包含计算的成员.
const enum Dire {blue,yellow,red,black}let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];DireRes // [0,1,2,3]
外部枚举
外部枚举只会用于编译时的检查,使用declare enum来进行定义
declare enum Dire {blue,yellow,red,black}let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];
编译后的结果如下,可以看到declare enum定义的枚举对象在结果中被删除
var DireRes = [0 /* blue */, 1 /* yellow */, 2 /* red */, 3 /* black */];
同时使用declare和const也是可以的。
declare const enum Dire {blue,yellow,red,black}let DireRes = [ Dire.blue, Dire.yellow, Dire.red, Dire.black ];DireRes //[ 0, 1, 2, 3 ]
