本節介紹 ts 中泛型的常用情景
1 什么是泛型
泛型的本質是參數化類型,也就是說所操作的數據類型被指定為一個參數。這種參數類型可以用在類、接口和方法的創建中,分別稱為泛型類、泛型接口、泛型方法。
泛型使用<T>
來定義類型,<T>
中的T
,也可以是U
也可以是其他合法的字母,建議大寫。
泛型可以理解為不確定單獨類型
,函數中使用泛型,可以約束函數的參數和返回值類型相同。
2 泛型方法
比如我們定義一個 sum
方法
function sum(a:number): number {return a + a
}
這種定義的方法,我們傳入的參數 a
以及函數返回的數據 只能是 number
類型,不能是其他類型數據,否則會報錯;但是我們通常需要的類型會很多,這時我們可以定義一個類似通用的函數;
可能有同學會說我們可以定義一個any 類型的呀
,但是這樣就違背我們使用ts的初衷
了,
那么我們可以這樣寫
T
:表示類型變量,而這個變量只能是 類型,而不是值;
function sum<T>(a:T):T{return a +a
}
那么我們在使用的時候可以這樣寫
const a = sum<string>('2')
// 4 指定泛型此時的類型是 string,則傳入的值也必須是String類型
const b = sum<number>(4)
// 8 指定泛型此時 的類型是 number,則傳入的值,以及返回的值均為 Number 類型數據
3 傳入多個泛型
const fun = <T,U>(a:T, b:U) => {console.log(a, b)
}
此時的 a,b
可以是不同的類型,也可以是相同的類型
使用
fun<string, number>('1', 2) // '1', 2傳入的是a參數約定是 String類型b參數約定是 number 類型
4 常用的泛型名稱
T
:Type
的縮寫,類型
K、V
:key和value
的縮寫,鍵值對
E
:Element
的縮寫,元素
O
:Object
的縮寫,對象
5 泛型接口
一般的函數接口我們這樣定義
interface Person {(value1: string, value2: string): string;
}
當我們定義泛型函數接口時候可以這樣寫
interface Person<T> {(value: T): T;
}
或者
interface Person {<T>(value: T): T;
}
// 使用泛型 約定為 string類型
let nam: Person<string> = 'Andy'
定義一般泛型接口
還可以指定默認的類型
interface Person<T=string, U=number>{age: T;name: U;
}
6 泛型約束
比如我們想要傳入的參數中有必須有某種類型
interface Say {length: number;
}
function Person<T extends Say>(arg: T) {console.log(arg.length);// 此時arg參數中必須含有 length屬性,并且屬性的類型是 number,否則就會報錯
}
T extends表示傳入的類型必須是extends后面的類型或者子類型。
例如:
Person({length:10, name: 'Andy'}) // 傳入一個含有length 屬性的數據
Person([1,2,3,4,5,6,7,8,9]) // 數組類型默認含有 length 屬性
Person('123444') // String 類型數據自帶 length 屬性