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
廣告