列舉(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:

打錯字會出現警告且無法編譯:

最後,實務上一定會遇到數字、字串與列舉相互轉換的情境,說明如下:

  1. 列舉與數字互換
    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;
  2. 列舉與字串互換
    前面提到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

Comments

Be the first to post a comment

Post a comment