是說TS針對型別的類型也太講究,寫好多天還沒寫完(其實是我30篇不夠XDD),哈哈不囉嗦, 今天繼續筆記列舉(Enums)型別。
列舉(Enums)型別用於取值被限定在一定範圍內的場景,可以用來管理多個同系列的常數,作為狀態判斷使用。比如一週只能有七天,顏色限定為紅綠藍等。也可以自定義來表示每一個值。
使用enum
關鍵字來定義:
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
這時候我們來看編譯後,列舉成員會被賦值為從 0 開始自動遞增的數字,同時也會對列舉值到列舉名進行反向對映:
var Days;
(function (Days) {
Days[Days["Sun"] = 0] = "Sun";
Days[Days["Mon"] = 1] = "Mon";
Days[Days["Tue"] = 2] = "Tue";
Days[Days["Wed"] = 3] = "Wed";
Days[Days["Thu"] = 4] = "Thu";
Days[Days["Fri"] = 5] = "Fri";
Days[Days["Sat"] = 6] = "Sat";
})(Days || (Days = {}));
可以手動去定義不同的值。
enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
編譯後:
var Days;
(function (Days) {
Days[Days["Sun"] = 7] = "Sun";
Days[Days["Mon"] = 1] = "Mon";
Days[Days["Tue"] = 2] = "Tue";
Days[Days["Wed"] = 3] = "Wed";
Days[Days["Thu"] = 4] = "Thu";
Days[Days["Fri"] = 5] = "Fri";
Days[Days["Sat"] = 6] = "Sat";
})(Days || (Days = {}));
如果中間突然指定了了一個值,那他會從當前的值從新開始計算。如下, Days[3]
的值先是 "Sun"
,而後又被 "Wed"
覆蓋了。這個TypeScript 是不會報錯的,所以要特別注意。
enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 3); // true
console.log(Days["Wed"] === 3); // true
console.log(Days[3] === "Sun"); // false
console.log(Days[3] === "Wed"); // true
手動賦值的列舉項其中一個不想是數字,此時可以使用 any 型別斷言來讓TypeScript 無視型別檢查。
enum Days {Sun = 7, Mon, Tue, Wed, Thu, Fri, Sat = <any>"S"};
編譯後:
var Days;
(function (Days) {
Days[Days["Sun"] = 7] = "Sun";
Days[Days["Mon"] = 8] = "Mon";
Days[Days["Tue"] = 9] = "Tue";
Days[Days["Wed"] = 10] = "Wed";
Days[Days["Thu"] = 11] = "Thu";
Days[Days["Fri"] = 12] = "Fri";
Days[Days["Sat"] = "S"] = "Sat";
})(Days || (Days = {}));
字串 enums 沒有number enums 可以自動遞增的行為, 但字串enum自行定義是有他的語意在的。
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
雖然enum可以混合數字與字串,但盡量不要寫這種寫法:
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
列舉項有兩種型別:常數項(constant member)和計算所得項(computed member)。
前面我們所舉的例子都是常數項,一個典型的計算所得項的例子如下, "blue".length
就是一個計算所得項。:
enum Color {Red, Green, Blue = "blue".length};
console.log(Color.Blue); //4
像是二元運算子 <<
、 |
、&
等都歸為常數項:
enum FileAccess {
// constant members
None,
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
// computed member
G = "123".length,
}
可以使用 const enum 定義的列舉型別:
const enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
常數列舉與普通列舉的區別是,它會在編譯階段被刪除,並且不能包含computed member(計算成員), 只能是常數項(constant member)。
編譯後:
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];
外部列舉(Ambient Enums)是使用 declare enum 定義的列舉型別:
declare enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
declare 定義的型別只會用於編譯時的檢查,編譯結果中會被刪除。
編譯後:
var directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];
下一篇終於來介紹interface了!! 撒花~
https://willh.gitbook.io/typescript-tutorial/advanced/enum#chang-shu-xiang-he-ji-suan-suo-de-xiang
https://www.typescriptlang.org/docs/handbook/enums.html