枚舉
枚舉(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
定義的類型只會用於編譯時的檢查,編譯結果中會被刪除。
外部枚舉和非外部枚舉之間有一個重要的區別,在正常的枚舉裏,沒有初始化方法的成員被當成常數成員。 對於非常數的外部枚舉而言,沒有初始化方法時被當做需要經過計算的。
外部枚舉與聲明語句一樣,常出現在聲明文件中。
同時使用 declare
和 const
也是可以的:
declare const enum Directions { up, down, left, right };
let directions = [Directions.up,Directions.down,Directions.left,Directions.right];
//[0, 1, 2, 3]