使用枚举可以给难以理解的常量定义一些直观容易理解的名字,更清晰的表达常量的意义。Typescript 支持数字和字符串的枚举。
1.数字枚举
enum Direction {
Up = 1,
Down,
Left,
Right
}
Up使用初始化为 1。 其余的成员会从 1开始自动增长。 换句话说, Direction.Up的值为 1, Down为 2, Left为 3, Right为 4。
enum Day {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
上面的枚举类型Day,默认会从 0 开始给每个值一个编号,SUNDAY = 0,其余依次增加1,经过编译后就是如下:
"use strict";
var Day;
(function (Day) {
Day[Day["SUNDAY"] = 0] = "SUNDAY";
Day[Day["MONDAY"] = 1] = "MONDAY";
Day[Day["TUESDAY"] = 2] = "TUESDAY";
Day[Day["WEDNESDAY"] = 3] = "WEDNESDAY";
Day[Day["THURSDAY"] = 4] = "THURSDAY";
Day[Day["FRIDAY"] = 5] = "FRIDAY";
Day[Day["SATURDAY"] = 6] = "SATURDAY";
})(Day || (Day = {}));
通过 点访问枚举集合中的成员:
enum Day {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
console.log(Day.SUNDAY, Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY, Day.THURSDAY, Day.FRIDAY, Day.SATURDAY) // 0 1 2 3 4 5 6
2.字符串枚举
在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。
enum RequestEnum {
GET = 'GET',
POST = 'POST',
PATCH = 'PATCH',
PUT = 'PUT',
DELETE = 'DELETE',
}
enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',
// json
TEXT = 'text/plain;charset=UTF-8',
// form-data 一般配合qs
FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
// form-data 上传
FORM_DATA = 'multipart/form-data;charset=UTF-8',
}
3.异构枚举
异构枚举是指枚举中既有字符串枚举又有数字枚举
enum ResultEnum {
SUCCESS = 200,
ERROR = -1,
TIMEOUT = 10042,
TYPE = 'success',
}
在开发中不建议使用异构枚举,因为枚举是将同一类值整理为一个集合,比如都是请求状态码,或者都是请求提示信息。
4.常量枚举
在Typescript 中我们正常定义一个枚举类型,在编译成JavaScript代码后就会创建一个对象,这个对象会在程序运行时使用,但如果我们只是单纯的想让程序代码的可读性好,并不需要编译后的对象的话,就会增加编译后的代码量,Typescript中有一个const enum (常量枚举),在enum前增加const,编译后的代码就不会创建这个对象,只会从枚举里拿到相应的值进行替换。为了避免在额外生成的代码上的开销和额外的非直接的对枚举成员的访问,我们可以使用 const枚举。
const enum Day {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
console.log(Day.SUNDAY, Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY, Day.THURSDAY, Day.FRIDAY, Day.SATURDAY) // 0 1 2 3 4 5 6
编译后的代码:
"use strict";
console.log(0 /* SUNDAY */, 1 /* MONDAY */, 2 /* TUESDAY */, 3 /* WEDNESDAY */, 4 /* THURSDAY */, 5 /* FRIDAY */, 6 /* SATURDAY */); // 0 1 2 3 4 5 6
它们在编译阶段会被删除, 常量枚举成员在使用的地方会被内联进来。 之所以可以这么做是因为,常量枚举不允许包含计算成员,如果包含了计算成员那就需要编译后的代码进行计算,不能删除。
const enum Enum {
A
}
let aa = Enum.A;
let nameOfA = Enum[aa]; // A const enum member can only be accessed using a string literal.const in an enum means the enum is fully erased, which means you can't index it by an arbitrary value. Just remove the const modifier.
//只有使用字符串文本才能访问常数枚举成员。 枚举中的const意味着枚举完全删除,这意味着您无法通过任意值索引。只需删除Const修改器。
编译后的枚举如下:
"use strict";
var aa = 0 /* A */;
var nameOfA = Enum[aa]; // "A"
结合上面的报错信息,编译后的代码没有枚举对象,获取不到 aa的信息。
5.联合枚举与枚举成员的类型
存在一种特殊的非计算的常量枚举成员的子集:字面量枚举成员。 字面量枚举成员是指不带有初始值的常量枚举成员,或者是值被初始化为
- 任何字符串字面量(例如: “foo”, “bar”, “baz”)
- 任何数字字面量(例如: 1, 100)
- 应用了一元 -符号的数字字面量(例如: -1, -100)
当所有枚举成员都拥有字面量枚举值时,它就带有了一种特殊的语义。
首先,枚举成员成为了类型! 例如,我们可以说某些成员 只能是枚举成员的值:
enum ShapeKind {
Circle,
Square,
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
sideLength: number;
}
let c: Circle = {
kind: ShapeKind.Square,
// ~~~~~~~~~~~~~~~~ Error!
radius: 100,
}
6.反向映射
反向映射只支持数字枚举。即可以从枚举值获取到枚举名:
enum Status {
Success = 200,
NotFound = 404,
Error = 500
}
console.log(Status["Success"]); // 200
console.log(Status[200]); // 'Success'
console.log(Status[Status["Success"]]); // 'Success'