TypeScript - 型別推斷



型別推斷是 TypeScript 的一項特性,允許編譯器自動確定(推斷)變數、函式或表示式的型別。TypeScript 是一種可選靜態型別程式語言。您可以宣告變數、表示式或函式,而無需顯式註釋它們的型別。編譯器將在編譯時自動確定型別。

型別推斷可以基於許多因素進行,包括:

  • 分配給變數的值的型別。

  • 傳遞給函式的函式引數或引數的型別。

  • 函式返回值的型別。

  • 物件和屬性的型別。

讓我們來看一個簡單的例子:

let x = 5;
let y = "Hello World!";

在上面的程式碼中,TypeScript 編譯器可以推斷出變數 x 的型別為 number。這是因為變數 x 正在被賦值一個數字。編譯器還可以推斷出 y 的型別為 string,因為 y 正在被賦值一個字串。

在上面的例子中,TypeScript 自動根據分配給它們的值推斷變數的型別。

變數或成員初始化

可以使用變數和成員初始化來推斷型別。TypeScript 編譯器根據初始化值推斷變數的型別。

示例

讓我們來看一個變數初始化的例子:

let x = 20;
let y = "Hello World!";
let z = true;
console.log("type of x: ", typeof x);
console.log("type of y: ", typeof y);
console.log("type of z: ", typeof z);

編譯後,它將生成相同的 JavaScript 程式碼。

上面示例程式碼的輸出如下:

type of x:  number
type of y:  string
type of z:  boolean

讓我們來看一個物件成員初始化的例子:

class Person {
  name = "Shahid";
  age = 35;
}
const p = new Person();
// Prints name and age
console.log(`${p.name}, ${p.age}`);

編譯後,它將生成以下 JavaScript 程式碼。

class Person {
    constructor() {
        this.name = "Shahid";
        this.age = 35;
    }
}
const p = new Person();
// Prints name and age
console.log(`${p.name}, ${p.age}`);

上面程式碼的輸出如下:

Shahid, 35

函式預設引數

當引數用預設值初始化時,typescript 編譯器也可以推斷函式引數的型別。

在下面的例子中,引數 x 和 y 用預設值初始化。編譯器將 x 和 y 的型別推斷為 number。這是因為初始化值是數字。

function add(x = 10, y = 30){
   return x + y;
}
let res = add(2,3);
console.log(res);

編譯後,它將生成相同的 JavaScript 程式碼。

上面示例程式碼的輸出如下:

5

現在讓我們嘗試將引數作為字串值傳遞。

let res2 = add('2', '3');

函式 add 的引數型別被推斷為 number,因此當我們將字串型別的引數傳遞給函式時,它會顯示以下錯誤:

Argument of type 'string' is not assignable to parameter of type 'number'.

函式返回型別

TypeScript 編譯器根據返回值的型別推斷函式返回型別的型別。

如果函式不返回任何值,則返回型別為 void。

在下面的例子中,函式 add 接受兩個數字並返回它們的和。由於兩個數字的和是數字,因此返回值的型別是 number。因此,編譯器將函式 add 的返回型別推斷為 number。

function add(x: number, y: number){
   return x + y;
}
let res1: number = add(2,3);
console.log(res1);

當我們將函式 add 的返回值賦給 string 型別的變數 (res2) 時,它將顯示錯誤。

let res2: string = add(2,3); 

錯誤如下:

Type 'number' is not assignable to type 'string'.

這是因為函式 add 的返回型別是 number,而我們將其賦值給 string 型別的變數。

最佳通用型別:聯合型別

使用變數初始化、函式預設引數和返回型別進行型別推斷很簡單。

當 TypeScript 從多個表示式推斷型別時,表示式的型別被確定為“最佳通用型別”。

讓我們透過一個例子來理解這一點:

const a = [5, 10, "TypeScript"];

在上面的例子中,陣列包含值 – 5、10 和 "TypeScript"。為了推斷陣列的型別,我們必須考慮每個元素的型別。這裡,我們有陣列型別的選擇,例如 number 和 string。推斷出的陣列型別應該是陣列中每個值的最佳通用型別。

最佳通用型別必須從提供的候選型別中選擇。如果所有候選型別都沒有超型別,則使用聯合型別。因此,上面陣列的推斷型別為:

(number | string)[]

上面的陣列只能包含 number 和 string 型別的數值。如果您嘗試新增不同於 number 和 string 的型別的值,它將顯示錯誤。

讓我們嘗試向陣列新增一個布林值。

const a = [5, 10, "TypeScript"];
a.push(true);

上面的程式碼將顯示以下編譯錯誤:

型別“boolean”的引數不能分配給型別“string | number”的引數。

上下文型別

上下文型別是 TypeScript 中的一項特性,允許編譯器根據變數、引數或表示式使用的上下文推斷其型別。例如,

window.onmousedown = function (mouseEvent) {
  console.log(mouseEvent.button);
}

在上面的例子中,TypeScript 使用 Window.onmousedown 函式的型別來推斷賦值右側函式表示式的型別。因此,它能夠推斷 mouseEvent 引數的型別為 MouseEvent。透過這種方式,TypeScript 推斷 mouseEvent 具有 button 屬性,並且不會顯示編譯錯誤。

上下文型別在編寫簡潔的程式碼的同時不損失型別安全方面非常有用。

廣告