Quickly Uderstand TypeScript Generics
速通了解 TypeScript 泛型
前言
對於 TypeScript 的泛型 我一直有種恐懼,什麼滿滿的 <T>、<U>、extends、多層嵌套,看起來就很可怕。畢竟在日常開發裡,好像也不太需要……對吧?的確解決小問題如此,但在特定問題下泛型將會非常必要。
什麼原因需要有泛型存在?
通常在規劃可重複運用的代碼片段時會需要泛型,具體來說:
- 某個型別要進行轉換(Utility Types)
- 某個函式要接受不同資料型態的輸入……
- 某個元件要接受不同資料型態的輸入……(Vue Generic)
泛型本身很簡單
泛型 = 型別版本的參數
相較於賦予函式參數具體型別過於死板:
function print(message: string): string { return message}print('hi')print(123) // Argument of type 'number' is not assignable to parameter of type 'string'透過泛型使定義的型別更具彈性並可重複利用:
function print<MessageType>(message: MessageType): MessageType { return message}
print('hi') // function print<"hi">(message: "hi"): "hi"print(123) // function print<123>(message: 123): 123可想像 <MessageType> 泛型型別相當於透過 message 推斷而生。
extends - 泛型限制
透過關鍵字 extends 縮限泛型的可能性:
function print<MessageType extends string | number>(message: MessageType): MessageType { return message}
print('hi')print(123)print(false) // Argument of type 'boolean' is not assignable to parameter of type 'string | number'.相較於「名詞(A 是 string)」更類似「形容詞(A 擁有 string 或 number 特性)」。
Conditional types - 條件型別
使用類似JavaScript 條件運算子的語法基於 extends 的判斷可以轉換出不同的型別:
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // truetype B = IsString<number>; // false總結
學習泛型可用於打造更泛用的型別與程式
每次看到多層嵌套複雜的條件型別,都認真尊敬生產等級的 TypeScript 庫需要大量的心力維護和安排。