泛型基礎
泛型允許我們在定義函數、類或接口時使用參數化類型,從而實現代碼的通用性。例如:
function identity<T>(arg: T): T {return arg;
}let output = identity<string>("hello");
console.log(output); // 輸出:hello
在上面的例子中,<T>
表示這是一個泛型函數,它接受一個類型為 T
的參數 arg
,并返回相同類型的值。我們在調用 identity
函數時指定了類型參數為 string
,從而確保返回值的類型與輸入值相同。
泛型類型
除了函數之外,我們還可以使用泛型來定義接口和類。例如:
interface Pair<T, U> {first: T;second: U;
}let pair: Pair<number, string> = { first: 1, second: "two" };
console.log(pair); // 輸出:{ first: 1, second: 'two' }
在上面的例子中,我們定義了一個名為 Pair
的泛型接口,它接受兩個類型參數 T
和 U
,并具有 first
和 second
兩個屬性,分別對應這兩種類型。
泛型約束
有時候,我們希望泛型具有某些特定的行為或屬性。在這種情況下,我們可以使用泛型約束來限制泛型的類型。例如:
interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);return arg;
}loggingIdentity("hello"); // 輸出:5
在上面的例子中,我們使用了泛型約束 extends Lengthwise
,表示 T
必須具有 length
屬性。這樣,我們就可以在函數中安全地訪問 length
屬性,而不必擔心類型錯誤。
泛型在類中的應用
泛型不僅可以應用于函數和接口,還可以應用于類。例如:
class Box<T> {private value: T;constructor(value: T) {this.value = value;}getValue(): T {return this.value;}
}let box = new Box<number>(42);
console.log(box.getValue()); // 輸出:42
在上面的例子中,我們定義了一個名為 Box
的泛型類,它接受一個類型參數 T
,并具有一個 getValue
方法,返回泛型類型 T
的值。
泛型與類型推斷
TypeScript 具有強大的類型推斷能力,可以根據上下文推斷泛型的類型,從而使代碼更加簡潔和易讀。例如:
function identity<T>(arg: T): T {return arg;
}let output = identity("hello");
console.log(output); // 輸出:hello
在上面的例子中,盡管我們沒有顯式地指定類型參數,但 TypeScript 仍然能夠推斷出 output
的類型為 string
,因為參數 "hello"
的類型是已知的。
泛型的優勢與應用場景
泛型可以使我們編寫更加通用和靈活的代碼,提高代碼的重用性和可維護性。它在許多場景下都有著廣泛的應用,例如容器類、函數庫、異步編程等。通過合理地運用泛型,我們可以編寫出更加健壯和可擴展的程序。