泛型
1姓赤、什么是泛型
當需要一個函數(shù)或類支持多種數(shù)據(jù)類型時刊苍,具有很高的靈活性既们,此時泛型就出現(xiàn)了。
泛型的含義為:不預(yù)先確定函數(shù)類型正什,具體的類型在使用時才確認啥纸。
function log(value:string):string { // 目前只接受字符串類型的參數(shù)
console.log(value);
return value;
}
// 如果接受一個字符串數(shù)組,可通過函數(shù)重載實現(xiàn)
function log (value: string): string;
function log (value: string[]): string [];
function log (value: any) {
console.log(value);
return value;
}
// 聯(lián)合類型也可實現(xiàn)
function log (value: string | string []) :string | string [] {
console.log(value);
return value;
}
// 如果接受任何類型的參數(shù)該如何處理
// 方法: any
function log (value: any) { // 但是此方法忽略了輸入的類型和返回的類型必須是一致的這種關(guān)系
console.log(value);
return value;
}
// 使用泛型實現(xiàn)
function log<T>(value: T): T { // 類型 T 不需要預(yù)先的指定婴氮,可保證輸入?yún)?shù)類型和輸出是一致的
console.log(T);
return T;
}
// 使用時斯棒,可直接指定數(shù)據(jù)的類型
log<string[]>(['a','b']);
log(['a','b']); // 利用 ts 的類型推斷,不指定數(shù)據(jù)類型
2主经、泛型函數(shù)與泛型接口
2.1 泛型函數(shù)
泛型可以定義函數(shù)荣暮,也可以定義函數(shù)類型;
// 泛型函數(shù)的實現(xiàn)
type Log = <T>(value: T): T;
let mylog :Log = log;
2.2 泛型接口
interface Log {
<T>(value: T): T // 只約束方法
}
interface Log<T> { // 約束所有成員類型
(value: T): T
}
3罩驻、泛型類與泛型約束
3.1 泛型類
泛型可以約束類的成員
class Log<T> { // 將泛型類放在類名的后面穗酥,可以約束所有的成員
run(value: T) {
console.log(value)
return value
}
}
需要注意的是,泛型不能用于類的靜態(tài)成員惠遏。如果此時 run 的修飾符為 static砾跃,那么編譯器會報錯:靜態(tài)類型不能引用類類型參數(shù)。根據(jù)以上节吮,實例化一個方法:
let log1 = new Log<number>(); // 實例化的時候抽高,需要指定泛型的類型
log1.run(1); // 此時入?yún)⒅荒苁?number 類型
let log2 = new Log(); // 如果不指定類型,那么成員入?yún)⒖墒侨我忸愋?log2.run({});
3.2 泛型約束
改造一下 log 方法:
function log<T>(value: T): T {
console.log(value, value.length); // 打印 value 的屬性透绩,此時會報錯厨内, T 類型上不存在 length 屬性
return value;
}
此時需要使用類型約束。定義一個接口渺贤,然后讓 T 繼承字這個接口:
interface Length {
length: number
}
function log<T extends Length>(value: T): T { // 此時,T 收到類型約束请毛,不是所有類型都可以傳入志鞍,輸入的參數(shù)不管是什么類型,但是必須具有 length 屬性
console.log(value, value.length);
return value;
}
// 只要入?yún)в?length 屬性即可
log([1])
log('123')
log({ length: 3 })
總結(jié)方仿,泛型的優(yōu)點在于:
- 函數(shù)和類可以輕松的支持多種類型固棚,增強程序的擴展性
- 不必寫多條函數(shù)重載,冗長的聯(lián)合類型聲明仙蚜,增強代碼可讀性
- 靈活控制類型之間的約束