TypeScript程式語言的列舉,是TypeScript特有、JavaScript沒有的東西。列舉可以快速地將多個不同的值加上名稱並群組化。
直接舉個例子來說明TypeScript列舉的用法:
enum Level {
One,
Two,
Three
}
console.log(Level.One);
console.log(Level.Two);
console.log(Level.Three);
以上程式的輸出結果如下:
1
2
預設的列舉,可以直接定義出數個名稱,稱為變體(Variant),每個變體所代表的值即為它們的序數(ordinal),從0
開始數。
如果我們要改變變體所代表的數值,可以在變體後面使用=
來指派數值。一旦有變體的值是明確指派某個數值的話,這個變體後面的其它變體的值就會預設是這個變體的值加N
,N
為這個變體與其它變體的序數差。
列舉的變體可以透過在列舉名稱後加上句點.
的方式來讀取,但它的值無法被改變。
例如:
enum Level {
One,
Two = 10,
Three ,
Four,
Five = 20.5,
Six
}
console.log(Level.One);
console.log(Level.Two);
console.log(Level.Three);
console.log(Level.Four);
console.log(Level.Five);
console.log(Level.Six);
以上程式的輸出結果如下:
10
11
12
20.5
21.5
如果指派給變體的值不是數值的話,則這個變體之後的值必須要手動指派,不然會編譯錯誤。
例如:
enum Level {
One,
Two = 10,
Three,
Four,
Five = 20.5,
Six,
Seven = "25",
Eight = 30,
Night
}
console.log(Level.One);
console.log(Level.Two);
console.log(Level.Three);
console.log(Level.Four);
console.log(Level.Five);
console.log(Level.Six);
console.log(Level.Seven);
console.log(Level.Eight);
console.log(Level.Night);
以上程式中的Eight
變體必須要手動指派值,因為Seven
變體的值不是數值。
列舉也是一個型別,例如:
enum Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
function isWeekend(day: Weekday) {
switch (day) {
case Weekday.Saturday:
case Weekday.Sunday:
return true;
default:
return false;
}
}
console.log(isWeekend(Weekday.Monday));
console.log(isWeekend(Weekday.Saturday));
isWeekend
函數有一個型別為Weekday
的day
參數,如果day
參數的值是Weekday.Saturday
或是Weekday.Sunday
的話,就回傳true
,否則回傳false
。
以上程式會輸出:
true
如果列舉的變體的值是數值的話,我們可以直接利用數值來表示該變體。例如以上程式可以修改如下:
enum Weekday {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
function isWeekend(day: Weekday) {
return day === 6 || day === 7;
}
console.log(isWeekend(1));
console.log(isWeekend(6));
定數型別
定數也可以直接當作型別來用,常拿來代替列舉。
例如:
function isWeekend(day: 1|2|3|4|5|6|7) {
return day === 6 || day === 7;
}
console.log(isWeekend(1));
console.log(isWeekend(6));
以上程式,isWeekend
函數的day
,只能傳入數值1~7。
再舉一個例子:
let o: { a: 1, b: 2 } = {a: 1, b: 2};
let a: [1, 2] = [1, 2];
let f: (n: 1) => 2 = (n) => 2;
以上程式,限定了o
物件只能是{ a: 1, b: 2 }
,a
陣列只能是[1, 2]
,f
函數只能是(n: 1) => 2
。
再來一個例子:
let o: { a: 1 | 2, b: number | string } = {a: 1, b: 2};
以上程式,限定了o
物件的a
屬性的值只能是1
或是2
,b
屬性的值只可以是數值或是字串型別。
TypeScript在推論const
宣告出來的常數型別時,如果常數值是基本資料型別,則其型別會被推論為定數型別(即直接將值當作型別),表示其無法被更改!
舉例來說:
const a = 1;
const b = "Hello!";
以上a
常數的型別為1
,b
常數的型別為"Hello!"
。
常數列舉
我們再來看這個例子:
enum Level {
One,
Two,
Three
}
console.log(Level.One);
console.log(Level.Two);
console.log(Level.Three);
以上程式在經過TypeScript編譯之後,得到的JavaScript程式碼如下:
var Level;
(function (Level) {
Level[Level["One"] = 0] = "One";
Level[Level["Two"] = 1] = "Two";
Level[Level["Three"] = 2] = "Three";
})(Level || (Level = {}));
console.log(Level.One);
console.log(Level.Two);
console.log(Level.Three);
如果我們確定這個列舉只會在這個程式專案下用到的話,可以在enum
關鍵字前面加上const
關鍵字,使其成為常數列舉。
例如:
const enum Level {
One,
Two,
Three
}
console.log(Level.One);
console.log(Level.Two);
console.log(Level.Three);
以上程式會被編譯為:
console.log(0);
console.log(1);
console.log(2);
看到以上的JavaScript程式就可以知道,我們應該要儘量使用常數列舉,讓JavaScript程式在執行階段不會有額外的開支(overhead)。
總結
在這個章節中我們學會了TypeScript提供的列舉用法,以及定數型別的用法。在下一個章節要來學習TypeScript提供的泛型(generic)用法。
下一章:TypeScript程式語言的泛型。