TypeScript 中的泛型乍看之下似乎令人畏懼——那些大寫字母和方括號是怎麼回事? 😅

但不用擔心,這份備忘錄有助於揭開泛型的神秘面紗,並透過簡單的範例向您展示它們如何運作。


泛型如何運作

泛型使您能夠定義一個類型變數,該變數充當稍後提供的特定類型的佔位符。這是泛型的核心優勢:它們允許您定義靈活、可重複使用的類型,而無需犧牲類型安全性。

按照慣例,字母 T 通常用於表示泛型類型變數,但您可以使用適合您的上下文的任何字母或描述性名稱(其他常用字母包括 U、V、K)。

使用範例

以下是一些示範泛型如何運作的實際範例。

您可以在這個TypeScript 遊樂場中使用下面的範例。

泛型函數

// A generic function that works with any data type
function identity<T>(arg: T): T {
    return arg;
}

// Using the generic function with different types
let num = identity<number>(42); // T is number
let str = identity<string>("Hello"); // T is string

在此範例中,T 是可以表示任何類型的類型參數。實際類型是在呼叫函數時確定的,無論是數字、字串或任何其他類型。

通用介面

在這裡,我們定義了一個具有兩個不同類型的屬性的介面 Pair。這些類型是在建立實例時指定的,可以是任何類型。唯一的限制是每個屬性都維護其各自的類型:兩個屬性不能屬於同一類型。

interface Pair<T, K> {
  first: T;
  second: K;
}

let pair: Pair<string, number> = { first: "one", second: 2 }
let anotherPair: Pair<number, string> = { first: 1, second: "second" }

泛型類型

泛型也可以應用於自訂類型。這個過程與介面類似:您可以使用佔位符類型定義形狀,這些佔位符類型是在使用該類型時確定的。泛型強制鍵入但不規定特定類型。

type Person<T, K, V> = {
  name: T,
  age: K,
  isMarried: V
}

const person1: Person<string, number, boolean> = {
  name: 'Bob',
  age: 67,
  isMarried: false
}

通用類別

通用類別可讓您定義資料類型靈活的藍圖,僅在建立實例時定義。在此範例中,Box 類別可以儲存任何類型的內容(例如,字串、數字或任何其他類型)。

class Box<T> {
  content: T

  constructor(content: T){
    this.content = content
  }

  getContent(): T {
    return this.content
  }
}

const letterBox = new Box('a')
const numberBox = new Box(1)

約束條件

泛型也支援約束,允許您限制可以使用的類型。例如,如果您只想支援具有 length 屬性的類型,則可以使用 extends 關鍵字強制執行此約束。它將泛型類型變數限制為特定類型或介面的子類型。這確保了泛型類型必須具有某些屬性或結構。

type LengthType = {length: number}
function getLength<T extends LengthType>(args: T){
  return args.length
}

getLength('abc')
getLength([1, 2])

//this doesn't work:
//getLength(2)
//getLength({"a": "b"})

實用程式類型

TypeScript 中的實用程式類型使用泛型來建立靈活且可重複使用的型別轉換。它們透過提供內建操作來簡化對現有類型的處理。

interface User {
  name: string;
  age: number;
  location: string;
}

//makes all properties optional 
const partialUser: Partial<User> = {name: 'Alice'}

//allows to omit properties: here the name property is omitted
const omitUser: Omit<User, 'name'> = {location: 'Berlin', age: 33}

我希望這有幫助!

如果您有任何疑問,請隨時與我們聯繫!您也可以在GithubLinkedInInstagram上找到我。


原文出處:https://dev.to/audreyk/typescript-generics-a-cheat-sheet-1a89


共有 0 則留言