[Medium] 泛型(Generics)
1. What are Generics?
什麼是泛型?
泛型(Generics)是 TypeScript 中一種強大的功能,允許我們建立可重用的元件,這些元件可以處理多種型別,而不是單一型別。
核心概念:在定義函式、介面或類別時,不預先指定具體的型別,而是在使用時再指定型別。
為什麼需要泛型?
沒有泛型的問題:
// 問題:需要為每種型別寫一個函式
function getStringItem(arr: string[]): string {
return arr[0];
}
function getNumberItem(arr: number[]): number {
return arr[0];
}
function getBooleanItem(arr: boolean[]): boolean {
return arr[0];
}
使用泛型的解決方案:
// 一個函式處理所有型別
function getItem<T>(arr: T[]): T {
return arr[0];
}
getItem<string>(['a', 'b']); // string
getItem<number>([1, 2, 3]); // number
getItem<boolean>([true, false]); // boolean
2. Basic Generic Syntax
基本泛型語法
泛型函式
// 語法:<T> 表示型別參數
function identity<T>(arg: T): T {
return arg;
}
// 使用方式 1:明確指定型別
let output1 = identity<string>('hello'); // output1: string
// 使用方式 2:讓 TypeScript 推斷型別
let output2 = identity('hello'); // output2: string(自動推斷)
泛型介面
interface Box<T> {
value: T;
}
const stringBox: Box<string> = {
value: 'hello',
};
const numberBox: Box<number> = {
value: 42,
};
泛型類別
class Container<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
get(index: number): T {
return this.items[index];
}
}
const stringContainer = new Container<string>();
stringContainer.add('hello');
stringContainer.add('world');
const numberContainer = new Container<number>();
numberContainer.add(1);
numberContainer.add(2);
3. Generic Constraints
泛型約束
基本約束
語法:使用 extends 關鍵字限制泛型型別。
// 約束 T 必須有 length 屬性
function getLength<T extends { length: number }>(arg: T): number {
return arg.length;
}
getLength('hello'); // ✅ 5
getLength([1, 2, 3]); // ✅ 3
getLength({ length: 10 }); // ✅ 10
getLength(42); // ❌ 錯誤:number 沒有 length 屬性
使用 keyof 約束
// 約束 K 必須是 T 的鍵
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = {
name: 'John',
age: 30,
email: 'john@example.com',
};
getProperty(user, 'name'); // ✅ 'John'
getProperty(user, 'age'); // ✅ 30
getProperty(user, 'id'); // ❌ 錯誤:'id' 不是 user 的鍵
多個約束
// T 必須同時滿足多個條件
function process<T extends string | number>(value: T): T {
return value;
}
process('hello'); // ✅
process(42); // ✅
process(true); // ❌ 錯誤:boolean 不在約束範圍內
4. Common Interview Questions
常見面試題目