TypeScript枚舉

枚舉

枚舉(Enum)類型用於取值被限定在一定範圍內的場景,比如一週只能有七天,顏色限定爲紅綠藍等

示例

使用枚舉來定義關鍵字

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};

枚舉成員會被賦值成從0開始,同行枚舉名和值也會進行反向映射:

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
console.log(Days[0] === 'Sun'); //true
console.log(Days['Sat'] === 6);//true

手動賦值

enum Days {Sun=7, Mon, Tue, Wed=1, Thu, Fri, Sat};

未被賦值的枚舉項會接着上一個枚舉項遞增 如:

上面的枚舉值會被編譯成以下結果
{1: "Wed", 2: "Thu", 3: "Fri", 4: "Sat", 7: "Sun", 8: "Mon", 9: "Tue", Sun: 7, Mon: 8, 
Tue: 9, Wed: 1, Thu: 2, Fri: 3, Sat: 4, Sun: 7, Mon: 8, Tue: 9 }

如果未被賦值的和手動賦值的重複了,TypeScript不會報錯,後者會覆蓋前者

所以使用的時候需要注意,最好不要出現這種覆蓋的情況

手動賦值的枚舉項可以不是數字,但是必須要使用類型斷言來人tsc無視類型檢查:

enum Days {Sun=7, Mon, Tue, Wed, Thu, Fri=({ value: 123, text: 'Fri'} as any), Sat=('Sat' as any)};

如果手動賦值的是非數字的話,手動賦值的枚舉項後面也必須都要賦值,否則會報錯:

enum Days {Sun=7, Mon, Tue, Wed, Thu, Fri=({ value: 123, text: 'Fri'} as any), Sat};
//Enum member must have initializer.

手動賦值也可以是小數或者負數,後續爲賦值的項仍是遞增加1

enum Days {Sun = 7, Mon = 1.5, Tue, Wed, Thu, Fri, Sat};

console.log(Days["Sun"] === 7); // true
console.log(Days["Mon"] === 1.5); // true
console.log(Days["Tue"] === 2.5); // true
console.log(Days["Sat"] === 6.5); // true

常數項和計算所得項

枚舉項有兩種類型:常數項(constant member)和計算所得項(computed member)。

enum Color {Red, Green, Blue = 'blue'.length};

'blue'.length就是計算所得項;

如果緊接着計算所得項後面是未手動賦值的項,那麼他就會因爲無法獲得初始值而報錯:

enum Color {Red = 'red'.length, Green, Blue};
//Enum member must have initializer.

滿足一下條件的枚舉成員被當做是常數:

  • 沒有初始化函數並且之前的枚舉成員是常數;這種情況下當前枚舉成員的值是上一個成員+1;第一個枚舉成員如果沒有初始化,那麼他的初始值爲0
  • 枚舉成員使用常數枚舉表達式初始化;常數枚舉表達式是 TypeScript 表達式的子集,它可以在編譯階段求值。當一個表達式滿足下面條件之一時,它就是一個常數枚舉表達式:

    • 數字字面量(即數字自己,不需要其他符號)
    • 引用之前定義的常數枚舉成員(可以是在不同的枚舉類型中定義的)如果這個成員是在同一個枚舉類型中定義的,可以使用非限定名來引用
    • 帶括號的常數枚舉表達式
    • +, -, ~ 一元運算符應用於常數枚舉表達式
    • +, -, *, /, %, <<, >>, >>>, &, |, ^ 二元運算符,常數枚舉表達式做爲其一個操作對象。若常數枚舉表達式求值後爲 NaN 或 Infinity,則會在編譯階段報錯

常數枚舉

常數枚舉是使用 const enum 定義的枚舉類型:

const enum Directions { up, down, left, right };
let directions = [Directions.up,Directions.down,Directions.left,Directions.right];
//[0, 1, 2, 3]

與普通枚舉的區別是在編譯階段會被刪除,並且不能包含計算成員。

const enum Color {Red, Green, Blue = 'blue'.length};
//const enum member initializers can only contain literal values and other computed enum values.

外部枚舉

外部枚舉用來描述已經存在的枚舉類型的形狀。

declare enum Directions { up, down, left, right };
let directions = [Directions.up,Directions.down,Directions.left,Directions.right];

declare 定義的類型只會用於編譯時的檢查,編譯結果中會被刪除。

外部枚舉和非外部枚舉之間有一個重要的區別,在正常的枚舉裏,沒有初始化方法的成員被當成常數成員。 對於非常數的外部枚舉而言,沒有初始化方法時被當做需要經過計算的。

外部枚舉與聲明語句一樣,常出現在聲明文件中。

同時使用 declareconst 也是可以的:

declare const enum Directions { up, down, left, right };
let directions = [Directions.up,Directions.down,Directions.left,Directions.right];
//[0, 1, 2, 3]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章