iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0

泛型 (Generics)

TypeScript 裡的泛型(Generics)允許我們在定義函式、類別或介面時不必指定具體的資料型別,而是使用佔位符<>,讓這些結構可以運作於不同的資料型別上。這樣的設計能夠提高程式的重用性和靈活性,並在編譯時提供更好的型別檢查。

  • 基本語法

在 TypeScript 中,使用泛型的基本語法是將型別參數放在尖括號(<>)中。型別參數可以是任何有效的識別符,通常會使用單個字母,例如 TUK 等。

function toArrayByParam<T>(param: T): T[] {
    return [param];
}

實際應用

泛型(Generics)不僅可以用於函式,還可以在類別和介面中使用,這使得程式碼更具靈活性和可重用性。以下分別介紹如何應用在各種型別上:

1. 泛型函式

泛型函式是泛型中最常見的使用場景。它允許我們在定義函式時不指定具體的型別,這樣可以讓函式接受不同型別的參數,並返回相應型別的結果。來看看簡單的範例:

function someContent<T>(arg: T): T {
    return arg;
}

// 使用範例
const num = someContent<number>(18);      // num 的型別是 number
const str = someContent<string>("hello"); // str 的型別是 string

在這個範例中,someContent 函式使用了型別參數 T,無論傳入何種型別,都能返回相同型別的值。

2. 泛型類別

泛型類別也可以讓我們定義一個類別,而該類別的屬性和方法可以接受多種型別,在實例化時可以確定具體型別。以下是一個堆疊類別的例子:

class GenericStack<T> {
    private items: T[] = [];

    push(item: T): void {
        this.items.push(item);
    }

    pop(): T | undefined {
        return this.items.pop();
    }

    isEmpty(): boolean {
        return this.items.length === 0;
    }
}

// 使用範例
const stack = new GenericStack<number>();
stack.push(1);
stack.push(2);
console.log(stack.pop()); // 2

在這裡,GenericStack 類別可以存儲任意型別的資料,根據需要使用不同的型別實例化它。

3. 泛型介面

泛型介面定義了具有泛型屬性的型別,這使得介面的使用更加靈活。下面是一個簡單的泛型介面範例:

interface Pair<K, V> {
    key: K;
    value: V;
}

const numberStringPair: Pair<number, string> = {
    key: 1,
    value: "One",
};

const stringBooleanPair: Pair<string, boolean> = {
    key: "isActive",
    value: true,
};

在這個範例裡,Pair 介面有兩個型別參數 KV,這使得我們可以靈活定義 key 和 value 的型別。

4. 型別別名+泛型型別

在前一篇文章中學到的型別別名(type)也可以用在定義泛型的型別。

type Input<T> = {
  value: T;
};

const numberInput: Input<number> = {
  value: 18,
};

const stringInput: Input<string> = {
  value: 'I am Annie.',
};

const numValue: number = numberInput.value;
console.log(numValue); // 18

const stringValue: string = stringInput.value;
console.log(stringValue); // I am Annie.

結論

泛型在函式、類別和介面中的使用,讓我們能夠創建靈活且可重用的程式碼。這不僅提高了型別安全性,還減少了冗餘代碼的產生。透過正確使用泛型,可以大幅提升 TypeScript 應用的可維護性和擴展性。這對於開發大型應用尤為重要,因為它能幫助開發者避免常見的型別錯誤,並在編譯時進行檢查。


上一篇
Day11:TypeScript 的型別別名 (Type Aliases)
下一篇
Day13:TypeScript 的類別(Classes)基礎
系列文
用 TypeScript 重新定義前端開發:30 天的實踐與思考30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言