列舉(Enumerate)是我愛用的TypeScript特性之一,它能嚴格限制數值範圍,較數字或字串安全,不慎打錯字在編譯時就會被揪出來,對於錯字成習甚至已發展成個人特色的我來說,節省了可觀的Debug時間,並大幅降低氣到想刴手指的風險,功德無量。(手指頭:謝謝你,TypeScript!)
TypeScript列舉轉換到JavaScript端的設計得挺巧妙,花了點時間才熟悉,順手整理筆記供大家參考。
TypeScript列舉宣告寫起來跟C#幾乎相同,但實際轉換成的JavaScript物件很有趣,例如以下的enum:
enum catgs {
Desktop, Pad, Phone
}
會產生一個名為catgs的物件,且包含六個屬性:
var catgs;
(function (catgs) {
catgs[catgs["Desktop"] = 0] = "Desktop";
catgs[catgs["Pad"] = 1] = "Pad";
catgs[catgs["Phone"] = 2] = "Phone";
})(catgs || (catgs = {}));
透過這六個屬性,就可以將0、1、2轉換成"Desktop"、"Pad"、"Phone",也能將"Desktop"、"Pad"、"Phone"轉換成0、1、2。
預設TypeScript會由0開始逐一為列舉項目編號,但我們也可以自訂對應的數值:
enum catgs {
Desktop = 10, Pad, Phone
} //結果:Desktop=10, Pad=11, Phone=12
enum flags {
Public = 1, Static = 2, Inherited = 4
} //也可設計成Flag應用
列舉宣告後,輸入程式時就能享受Intellisense:
打錯字會出現警告且無法編譯:
最後,實務上一定會遇到數字、字串與列舉相互轉換的情境,說明如下:
- 列舉與數字互換
TypeScript會將 var c1 = catgs.Desktop; 編譯成 var c1 = 0 /* Desktop */;故以JavaScript觀點,列舉型別本身就是數值,遇到TypeScript只接受數值型別的場合,直接把列舉當數字用就好,例如:呼叫外部函式時當數字參數用、做加減運算(可能會超出範圍破壞嚴謹性,不鼓勵)。
反之亦然,若數字要轉成列舉,不需任何轉換,直接指定即可。var c1 = catgs.Desktop;
//列舉型別可以直接當成數值數使用
var n:number = c1;
function x(v:number) {}
x(c1);
//列舉型別可以指定為對應數字
//但若給錯值編譯時不會發現,不建議使用
var c2:catgs = 1;
- 列舉與字串互換
前面提到catgs有六個屬性,在做字串轉換時就派上用場囉!不多說,直接看示範//列舉型別可以指定為對應數字
var c2:catgs = 1;
//傳入列舉對應數字可以取得文字
alert("c2 = " + catgs[c2]); //顯示c2 = Pad
//列舉型別不可以直接指定為列舉文字
//var c3:catgs = "Phone";//<--無法編譯
//傳入列舉文字可以取得對應數字,轉成列舉型別
var c4:catgs = catgs["Phone"];
alert("c4 = " + c4); // 顯示 c4 = Phone