TypeScript 枚举



TypeScript 中的枚举允许您定义一组命名常量。枚举是一种为一组数值赋予更友好的名称的方式。

每个枚举成员都有一个与其关联的值。该值可以是常量或计算值。成员值可以是数值或字符串值。

TypeScript 中的枚举类型是用户定义的数据类型。TypeScript 有一些特性不是 JavaScript 的类型级扩展。枚举是这些少数特性之一,还有类型守卫或联合类型。

enum enumName {
   // Enum members
}

TypeScript 中的枚举可以分为以下三种类型:

  • 数值枚举

  • 字符串枚举

  • 异构枚举

数值枚举

在这种类型的枚举中,枚举的成员被分配数值。数值枚举具有自动递增的特性。例如,如果我们将数字 5 分配给枚举的第一个常量变量,则后续的常量变量将分配递增的值,例如枚举的第二个成员为 6,下一个为 7,依此类推。

示例 1:默认数值枚举

默认情况下,TypeScript 中的枚举是数值的。第一个成员的值为 0,后续成员递增 1。

enum Weekday {
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
}
console.log(Weekday.Monday);
console.log(Weekday.Tuesday);
console.log(Weekday.Wednesday);
console.log(Weekday.Thursday);
console.log(Weekday.Friday);

编译后,它将生成以下 JavaScript 代码:

var Weekday;
(function (Weekday) {
    Weekday[Weekday["Monday"] = 0] = "Monday";
    Weekday[Weekday["Tuesday"] = 1] = "Tuesday";
    Weekday[Weekday["Wednesday"] = 2] = "Wednesday";
    Weekday[Weekday["Thursday"] = 3] = "Thursday";
    Weekday[Weekday["Friday"] = 4] = "Friday";
})(Weekday || (Weekday = {}));
console.log(Weekday.Monday);
console.log(Weekday.Tuesday);
console.log(Weekday.Wednesday);
console.log(Weekday.Thursday);
console.log(Weekday.Friday);

上面示例代码的输出如下:

0
1
2
3
4

请注意,第一个成员初始化为 0,后续成员递增 1。

示例 2:初始化数值枚举

在下面的示例中,我们创建了一个名为 Color 的枚举类型。在 Color 中,创建了三个名为 Red、Yellow 和 Green 的常量变量。我们初始化了第一个成员,并保留其他成员用于自动递增。

enum Color{
  Red = 10,
  Yellow,
  Green,
}
//print const variables values
console.log(Color.Red);
console.log(Color.Yellow);
console.log(Color.Green);

编译后,它将生成以下 JavaScript 代码:

var Color;
(function (Color) {
    Color[Color["Red"] = 10] = "Red";
    Color[Color["Yellow"] = 11] = "Yellow";
    Color[Color["Green"] = 12] = "Green";
})(Color || (Color = {}));
//print const variables values
console.log(Color.Red);
console.log(Color.Yellow);
console.log(Color.Green);

上面示例代码的输出如下:

10
11
12

示例 3:完全初始化的数值枚举

我们还可以设置枚举所有成员的值。在下面的示例中,我们初始化了 HttpStatus 枚举的所有成员。

enum HttpStatus {
  Success = 200,
  NotFound = 404,
  InternalServerError = 500,
}
console.log(HttpStatus.Success);
console.log(HttpStatus.NotFound);
console.log(HttpStatus.InternalServerError);

编译后,它将生成以下 JavaScript 代码:

var HttpStatus;
(function (HttpStatus) {
    HttpStatus[HttpStatus["Success"] = 200] = "Success";
    HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";
    HttpStatus[HttpStatus["InternalServerError"] = 500] = "InternalServerError";
})(HttpStatus || (HttpStatus = {}));
console.log(HttpStatus.Success);
console.log(HttpStatus.NotFound);
console.log(HttpStatus.InternalServerError);

上面示例代码的输出如下:

200
404
500

字符串枚举

字符串枚举类似于数值枚举,只是枚举成员的值被分配字符串而不是数值。字符串枚举不具有自动递增行为。

示例

以下示例创建一个名为 TrafficLight 的枚举,其中包含三个成员。这些成员初始化为字符串字面量。

enum TrafficLight {
  Red = "stop",
  Yellow = "caution",
  Green = "go",
}
console.log(TrafficLight.Red);
console.log(TrafficLight.Yellow);
console.log(TrafficLight.Green);

编译后,它将生成以下 JavaScript 代码:

var TrafficLight;
(function (TrafficLight) {
    TrafficLight["Red"] = "stop";
    TrafficLight["Yellow"] = "caution";
    TrafficLight["Green"] = "go";
})(TrafficLight || (TrafficLight = {}));
console.log(TrafficLight.Red);
console.log(TrafficLight.Yellow);
console.log(TrafficLight.Green);

上面示例代码的输出如下:

stop
caution
go

异构枚举

这是数值枚举和字符串枚举的组合。也就是说,在这种类型的枚举中,我们可以为其成员分配字符串值或数值。

示例

在下面的示例中,我们创建了一个 Student 的枚举类型。Student 中包含三个常量变量:Name、Gender 和 Mobile。Name 和 Gender 为字符串字面量类型,而 Mobile 为数值。

enum student{
  Name = "srujana",
  Gender = "female",
  Mobile = 901234567,
}
console.log(student.Name);
console.log(student.Gender);
console.log(student.Mobile);

编译后,它将生成以下 JavaScript 代码:

var student;
(function (student) {
    student["Name"] = "Srujana";
    student["Gender"] = "Female";
    student[student["Mobile"] = 901234567] = "Mobile";
})(student || (student = {}));
console.log(student.Name);
console.log(student.Gender);
console.log(student.Mobile);

上面示例代码的输出如下:

Srujana
Female
901234567

运行时枚举

枚举是在运行时存在的真实对象。在下面的示例中,枚举 E 作为参数对象传递给函数。它可以工作,因为 'E' 有一个名为 'y' 的属性,它是一个数字。

enum En {
  x,
  y,
  z,
}
 
function func(obj: { y: number }) {
  return obj.y;
}
console.log(func(En));
console.log(typeof En);

编译后,它将生成以下 JavaScript 代码。

var En;
(function (En) {
    En[En["x"] = 0] = "x";
    En[En["y"] = 1] = "y";
    En[En["z"] = 2] = "z";
})(En || (En = {}));
function func(obj) {
    return obj.y;
}
console.log(func(En));
console.log(typeof En);

上述代码的输出如下:

1
object

编译时枚举

当 TypeScript 枚举被编译时,它们会被转换为 JavaScript 对象。该对象将为每个枚举成员都具有一个属性,并且每个属性的值将是枚举成员的值。

数值和字符串枚举成员在编译时的行为有所不同。数值成员与其对应的 JavaScript 对象属性双向映射,而字符串成员与其运行时对象属性单向映射。

enum Enum {
  Name = 'John Doe',
  Age = 32,
}

上述 TypeScript 代码将编译成以下 JavaScript 代码:

var Enum;
(function (Enum) {
    Enum["Name"] = "John Doe";
    Enum[Enum["Age"] = 32] = "Age";
})(Enum || (Enum = {}));

请注意,编译后,Name 成员单向映射,而 Age 成员双向映射到其对应的运行时对象属性。

常量枚举

常量枚举是 TypeScript 中的特殊枚举,在编译过程中会被完全移除。这些枚举不包含在编译后的 JavaScript 输出中。

反向映射

如上所述,数值枚举成员编译后与其运行时对象属性双向映射。这称为反向映射。

enum Enum {
  A = 1,
}
console.log(Enum.A)
console.log(Enum['A'])
console.log(Enum[1]);

编译后,它将生成以下 JavaScript 代码。

var Enum;
(function (Enum) {
    Enum[Enum["A"] = 1] = "A";
})(Enum || (Enum = {}));
console.log(Enum.A);
console.log(Enum['A']);
console.log(Enum[1]);

上述代码的输出如下:

1
1
A

环境枚举

在 TypeScript 中,环境枚举用于描述已存在的枚举类型的形状。环境枚举不会生成任何 JavaScript 代码。要声明环境枚举,可以使用 declare 关键字。请看下面的例子:

declare enum Fruit {
    Apple,
    Orange,
    Banana,
}

上述代码声明了枚举的形状,而不会生成 JavaScript 代码。这意味着您可以在 TypeScript 代码中使用 Fruit 枚举,但它不会包含在编译后的 JavaScript 代码中。

对象与枚举

带有 as const 的对象可以满足枚举的需求。因此,在现代 TypeScript 中,您可能不需要枚举。当对象可以作为枚举工作时,为什么要使用不同的类型,而且对象也符合 JavaScript 的状态。

让我们看看枚举和带有 as const 的对象的示例。

// enum
enum EWeekend {  
  Saturday,  
  Sunday,
}  
console.log(EWeekend.Saturday)
// object with as const
const OWeekend = {
    Saturday: 0,
    Sunday: 1,
} as const;
console.log(OWeekend.Saturday);

编译后,它将生成以下 JavaScript 代码:

// enum
var EWeekend;
(function (EWeekend) {
    EWeekend[EWeekend["Saturday"] = 0] = "Saturday";
    EWeekend[EWeekend["Sunday"] = 1] = "Sunday";
})(EWeekend || (EWeekend = {}));
console.log(EWeekend.Saturday);
// object with as const
const OWeekend = {
    Saturday: 0,
    Sunday: 1,
};
console.log(OWeekend.Saturday);

上面示例代码的输出如下:

0
0

使用枚举作为函数参数

我们可以使用枚举作为函数定义中的参数。

enum Color {
  Red,
  Green,
  Blue,
}
function printColor(color: Color): void {
  console.log(color);
}
printColor(Color.Red); // Prints 0 to the console

在上面的示例中,函数 printColor() 接受 Color 类型的参数。它不返回任何内容,而是在控制台中记录颜色。

编译后,它将生成以下 JavaScript 代码:

var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
function printColor(color) {
    console.log(color);
}
printColor(Color.Red); // Prints 0 to the console

上面的示例代码将产生以下输出:

0
广告