前言
在上一篇文章TypeScript 学习笔记(八):类型断言中我们学习了TS
中的类型断言 ,本篇文章我们主要了解TS
中的枚举类型。
如果你也和我一样在为大厂冲刺的话,欢迎添加我的微信
lx3122178991
,这里有一群小伙伴有着和你同样的目标,欢迎来一起讨论,一同进步。
枚举是什么
枚举是一个被命名的整型常数的集合,用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型。通俗来说,枚举就是一个对象的所有可能取值的集合。
枚举的基本使用
在 TypeScript 中,我们可以使用 enum
关键字来定义枚举类型。例如:
TS
enum Direction {
Up,
Down,
Left,
Right,
}
上面的代码定义了一个名为 Direction
的枚举类型,它包含了四个成员:Up
、Down
、Left
和 Right
。默认情况下,枚举成员的值从 0 开始依次递增,即 Up
的值为 0,Down
的值为 1,以此类推。
如果只设定第一个成员的值,后面成员的值就会从这个值开始递增。
TS
enum Color {
Red = 7,
Green, // 8
Blue // 9
}
// 或者
enum Color {
Red, // 0
Green = 7,
Blue // 8
}
枚举成员的值可以是任意数值,但不能是大整数(Bigint)。
TS
enum Color {
Red = 90,
Green = 0.5,
Blue = 7n // 报错
}
枚举成员的值可以相同。
TS
enum Color {
Red = 0,
Green = 0,
Blue = 0
}
枚举成员的值也可以使用计算式。
TS
enum Permission {
UserRead = 1 << 8,
UserWrite = 1 << 7,
UserExecute = 1 << 6,
GroupRead = 1 << 5,
GroupWrite = 1 << 4,
GroupExecute = 1 << 3,
AllRead = 1 << 2,
AllWrite = 1 << 1,
AllExecute = 1 << 0,
}
enum Bool {
No = 123,
Yes = Math.random(),
}
Enum 成员值都是只读的,不能重新赋值。
TS
enum Color {
Red,
Green,
Blue
}
Color.Red = 4; // 报错
枚举的合并
同名的枚举结构会自动合并。
TS
enum Foo {
A,
}
enum Foo {
B = 1,
}
enum Foo {
C = 2,
}
// 等同于
enum Foo {
A,
B = 1,
C = 2
}
枚举结构合并时,只允许其中一个的首成员省略初始值,否则报错。
TS
enum Foo {
A,
}
enum Foo {
B, // 报错
}
枚举合并时,不能有同名成员,否则报错。
TS
enum Foo {
A,
B
}
enum Foo {
B = 1, // 报错
C
}
枚举类型有几种
枚举类型可以分成这三种:
- 数字枚举
- 字符串枚举
- 异构枚举
数字枚举
当我们声明一个枚举类型是,虽然没有给它们赋值,但是它们的值其实是默认的数字类型,而且默认从0开始依次累加:
TS
enum Direction {
Up, // 值默认为 0
Down, // 值默认为 1
Left, // 值默认为 2
Right // 值默认为 3
}
console.log(Direction.Up === 0); // true
console.log(Direction.Down === 1); // true
console.log(Direction.Left === 2); // true
console.log(Direction.Right === 3); // true
字符串枚举
枚举类型的值可以是字符串类型:
TS
enum Direction {
Up = 'Up',
Down = 'Down',
Left = 'Left',
Right = 'Right'
}
如果设定了一个变量为字符串之后,后续的字段也需要赋值字符串,否则报错:
TS
enum Direction {
Up = 'UP',
Down, // error TS1061: Enum member must have initializer
Left, // error TS1061: Enum member must have initializer
Right // error TS1061: Enum member must have initializer
}
异构枚举
异构枚举就是将数字枚举和字符串枚举结合起来混合起来使用。
TS
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
反向映射
数值枚举存在反向映射,即可以通过成员值获得成员名。
TS
enum Weekdays {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
console.log(Weekdays[3]) // Wednesday
上面示例中,Enum 成员Wednesday
的值等于3,从而可以从成员值3
取到对应的成员名Wednesday
,这就叫反向映射。
这是因为TS
会将上面的枚举结构,编译成下面的JS
代码。
JS
var Weekdays;
(function (Weekdays) {
Weekdays[Weekdays["Monday"] = 1] = "Monday";
Weekdays[Weekdays["Tuesday"] = 2] = "Tuesday";
Weekdays[Weekdays["Wednesday"] = 3] = "Wednesday";
Weekdays[Weekdays["Thursday"] = 4] = "Thursday";
Weekdays[Weekdays["Friday"] = 5] = "Friday";
Weekdays[Weekdays["Saturday"] = 6] = "Saturday";
Weekdays[Weekdays["Sunday"] = 7] = "Sunday";
})(Weekdays || (Weekdays = {}));
上面代码中,实际进行了两组赋值,以第一个成员为例。
JS
Weekdays[
Weekdays["Monday"] = 1
] = "Monday";
//实际等同于
Weekdays["Monday"] = 1;
Weekdays[1] = "Monday";
注意,这种情况只发生在数值枚举,对于字符串枚举,不存在反向映射。这是因为字符串枚举编译后只有一组赋值。
JS
enum MyEnum {
A = 'a',
B = 'b'
}
// 编译后
var MyEnum;
(function (MyEnum) {
MyEnum["A"] = "a";
MyEnum["B"] = "b";
})(MyEnum || (MyEnum = {}));