枚舉
使用枚舉可以定義一些具有名字的數字常量,和在C語言中一樣都是使用關鍵字enum
enum Direction { Up = 1, Down = 1<<2, Left, Right }
注意:一個枚舉類型可以有多個枚舉成員,每個枚舉成員都有一個對應的數字值,這個數字值可以是常數或者是計算得出的值。當滿足下列條件時,枚舉成員的數字值被認為是常數
- 不具有初始化函數並且之前的枚舉成員是常數。 在這種情況下,當前枚舉成員的值為上一個枚舉成員的值加1。 但第一個枚舉元素是個例外。 如果它沒有初始化方法,那么它的初始值為
0。 - 枚舉成員使用常數枚舉表達式初始化。 常數枚舉表達式是TypeScript表達式的子集,它可以在編譯階段求值。 當一個表達式滿足下面條件之一時,它就是一個常數枚舉表達式:
- 數字字面量
- 引用之前定義的常數枚舉成員(可以是在不同的枚舉類型中定義的) 如果這個成員是在同一個枚舉類型中定義的,可以使用非限定名來引用。
- 帶括號的常數枚舉表達式
+,-,~一元運算符應用於常數枚舉表達式+,-,*,/,%,<<,>>,>>>,&,|,^二元運算符,常數枚舉表達式做為其一個操作對象 若常數枚舉表達式求值后為NaN或Infinity,則會在編譯階段報錯。
例如:
enum Direction { //常數 Up, //0 Down = 3, //3 Left = Down + 4, //7 Right, //8 //計算的值 center = [1,2,3,4].length //4 }
注意:在枚舉類型中每個枚舉成員對應的數字值必須是唯一的,不能重復。如果有重復,則會取最后一個
enum Direction { //常數 Up, //0 Down = 3, //3 Left = Down + 4, //7 Right, //8 //計算的值 center = [1,2,3].length //3 } console.log(Direction.Down); //3 console.log(Direction[3]); //center
枚舉類型中是包含雙向映射的,即(value -> name)和(name -> value)
console.log(Direction.Down); //3 console.log(Direction[3]); //Down
常數枚舉
當訪問枚舉值時,為了避免生成多余的代碼和間接引用,可以使用常數枚舉。 常數枚舉是在enum關鍵字前使用const修飾符。
常數枚舉只能使用常數枚舉表達式並且不同於常規的枚舉的是它們在編譯階段會被刪除。 常數枚舉成員在使用的地方被內聯進來。 這是因為常數枚舉不可能有計算成員。
const enum Direction { //常數 Up, //0 Down = 3, //3 Left = Down + 4, //7 Right, //8 //計算的值 center = [1,2,3,4].length //error }
類型推論
TypeScript里,在有些沒有明確指出類型的地方,類型推論會幫助提供類型
let x = 'qwe';
變量x的類型被推斷為string。 這種推斷發生在初始化變量和成員,設置默認參數值和決定函數返回值時
最佳通用類型
有時需要從多個類型中推斷,這時會根據這些類型推斷出一個最合適的通用類型
let x = [0, 1, null];
為了推斷x的類型,我們必須考慮所有元素的類型。 這里有兩種選擇: number和null。 計算通用類型算法會考慮所有的候選類型,並給出一個兼容所有候選類型的類型
但是有時沒有一個類型能夠作為所有候選類型的類型,如果沒有找到最佳通用類型的話,類型推論的結果是空對象類型,{}。 因為這個類型沒有任何成員,所以訪問其成員的時候會報錯。
一般要明確的指出類型
上下文類型
TypeScript類型推論也可能按照相反的方向進行。 這被叫做“按上下文歸類”。按上下文歸類會發生在表達式的類型與所處的位置相關時。
上下文歸類會在很多情況下使用到。 通常包含函數的參數,賦值表達式的右邊,類型斷言,對象成員和數組字面量和返回值語句
window.onmousedown = function(mouseEvent) { console.log(mouseEvent.buton); //error };
之所以會報錯,是因為類型檢查器會根據賦值號=右邊來推斷參數mouseEvent的類型
如果上下文類型表達式包含了明確的類型信息,上下文的類型被忽略。 重寫上面的例子:
window.onmousedown = function(mouseEvent: any) { console.log(mouseEvent.buton); };
這個函數表達式有明確的參數類型注解,上下文類型被忽略。 這樣的話就不報錯了,因為這里不會使用到上下文類型
參考資料:
TypeScript中文網 · TypeScript——JavaScript的超集
