1. 程式人生 > 實用技巧 >TypeScript型別推論

TypeScript型別推論

介紹

這節介紹TypeScript裡的型別推論。即,型別是在哪裡如何被推斷的。

基礎

TypeScript裡,在有些沒有明確指出型別的地方,型別推論會幫助提供型別。如下面的例子

let x = 3;

變數x的型別被推斷為數字。 這種推斷髮生在初始化變數和成員,設定預設引數值和決定函式返回值時。

大多數情況下,型別推論是直截了當地。 後面的小節,我們會瀏覽型別推論時的細微差別。

最佳通用型別

當需要從幾個表示式中推斷型別時候,會使用這些表示式的型別來推斷出一個最合適的通用型別。例如,

let x = [0, 1, null];

為了推斷x的型別,我們必須考慮所有元素的型別。 這裡有兩種選擇: number

null。 計算通用型別演算法會考慮所有的候選型別,並給出一個相容所有候選型別的型別。

由於最終的通用型別取自候選型別,有些時候候選型別共享相同的通用型別,但是卻沒有一個型別能做為所有候選型別的型別。例如:

let zoo = [new Rhino(), new Elephant(), new Snake()];

這裡,我們想讓zoo被推斷為Animal[]型別,但是這個數組裡沒有物件是Animal型別的,因此不能推斷出這個結果。 為了更正,當候選型別不能使用的時候我們需要明確的指出型別:

let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];

如果沒有找到最佳通用型別的話,型別推斷的結果為聯合陣列型別,(Rhino | Elephant | Snake)[]

上下文型別

TypeScript型別推論也可能按照相反的方向進行。 這被叫做“按上下文歸類”。按上下文歸類會發生在表示式的型別與所處的位置相關時。比如:

window.onmousedown = function(mouseEvent) {
    console.log(mouseEvent.button);  //<- Error
};

這個例子會得到一個型別錯誤,TypeScript型別檢查器使用Window.onmousedown函式的型別來推斷右邊函式表示式的型別。 因此,就能推斷出 mouseEvent

引數的型別了。 如果函式表示式不是在上下文型別的位置, mouseEvent引數的型別需要指定為any,這樣也不會報錯了。

如果上下文型別表示式包含了明確的型別資訊,上下文的型別被忽略。 重寫上面的例子:

window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.button);  //<- Now, no error is given
};

這個函式表示式有明確的引數型別註解,上下文型別被忽略。 這樣的話就不報錯了,因為這裡不會使用到上下文型別。

上下文歸類會在很多情況下使用到。 通常包含函式的引數,賦值表示式的右邊,型別斷言,物件成員和陣列字面量和返回值語句。 上下文型別也會做為最佳通用型別的候選型別。比如:

function createZoo(): Animal[] {
    return [new Rhino(), new Elephant(), new Snake()];
}

這個例子裡,最佳通用型別有4個候選者:AnimalRhinoElephantSnake。 當然, Animal會被做為最佳通用型別。

詳細知識點見官方文件

TS官方文件