1.認(rèn)識(shí)泛型
我們?yōu)榱俗屵@個(gè)sum函數(shù),他具備通用性吧享,我這里得寫一大堆的聯(lián)合類型
而且對(duì)于這一大堆的聯(lián)合類型來說甲葬,他們還有一些共性,還有哪些共性呢辉饱,比如說如果我們是一個(gè)number類型和這個(gè)string類型的話搬男,他們是可以相加的,如果是我們后面這兩種類型的話鞋囊,它是可以獲取的length的止后,但是當(dāng)我們把這些所有的這些類型寫到一起的時(shí)候在這里做一些操作的時(shí)候,其實(shí)我們就需要一個(gè)一個(gè)對(duì)他們來做判斷了溜腐,因?yàn)槲覀冞@里這個(gè)number一樣译株,你看我把鼠標(biāo)放上來的時(shí)候,這個(gè)NUMBER它就可能是四種類型里面的其中一個(gè)挺益,我哪知道你是什么類型歉糜,根本就不知道,你只能在這里慢慢給他做一些判斷了望众。
在我們定義一個(gè)函數(shù)的時(shí)候匪补,除了我們的這個(gè)參數(shù)的值可以讓外界在調(diào)用的時(shí)候動(dòng)態(tài)決定之外伞辛,我們的這個(gè)參數(shù)的類型也應(yīng)該是可以讓外界來決定的。js沒有類型夯缺,但是ts有類型限制蚤氏,一般寫一個(gè)固定的類型的,才會(huì)有類型限制踊兜。
解決方法要把我們的類型進(jìn)行參數(shù)化竿滨,什么叫做類型參數(shù)化呢,意思是我這里到底是一個(gè)什么類型捏境,不是我在定義函數(shù)的時(shí)候決定定義的于游,在我們定義這個(gè)函數(shù)時(shí),我不決定這些參數(shù)的類型垫言,而是讓調(diào)用者以參數(shù)的形式告知我這里的函數(shù)參數(shù)應(yīng)該是什么類型贰剥。
2.泛型實(shí)現(xiàn)類型參數(shù)化
// 類型的參數(shù)化
// 在定義這個(gè)函數(shù)時(shí), 我不決定這些參數(shù)的類型
// 而是讓調(diào)用者以參數(shù)的形式告知,我這里的函數(shù)參數(shù)應(yīng)該是什么類型
function sum<Type>(num: Type): Type {
return num
}
// 1.調(diào)用方式一: 明確的傳入類型
sum<number>(20)
sum<{name: string}>({name: "why"})
sum<any[]>(["abc"])
// 2.調(diào)用方式二: 類型推到
sum(50)
sum("abc")
function foo<T, E, O>(arg1: T, arg2: E, arg3?: O, ...args: T[]) {
}
foo<number, string, boolean>(10, "abc", true)
3.泛型的基本補(bǔ)充
4.泛型接口
interface IPerson<T1, T2> {
name: T1;
age: T2;
}
const p: IPerson<string, number> = {
name: "why",
age: 18,
};
export {};
或者給IPerson一個(gè)默認(rèn)類型
interface IPerson<T1 = string, T2 = number> {
name: T1;
age: T2;
}
const p: IPerson = {
name: "why",
age: 18,
};
export {};
5.泛型類
class Point {
x: number;
y: number;
z: number;
constructor(x: number, y: number, z: number) {
this.x = x;
this.y = y;
this.z = y;
}
}
//const p1 = new Point("1.33.2", "2.22.3", "4.22.1")
//如果不想傳入number,而是字符串呢筷频?這時(shí)候不應(yīng)該把類的類型寫死
export {};
class Point<T> {
x: T
y: T
z: T
constructor(x: T, y: T, z: T) {
this.x = x
this.y = y
this.z = y
}
}
const p1 = new Point("1.33.2", "2.22.3", "4.22.1")
const p2 = new Point<string>("1.33.2", "2.22.3", "4.22.1")
const p3: Point<string> = new Point("1.33.2", "2.22.3", "4.22.1")
const names1: string[] = ["abc", "cba", "nba"]
const names2: Array<string> = ["abc", "cba", "nba"] // 不推薦(react jsx <>)
6.泛型的類型約束
// function getLength(arg: string | any[]) {
// return arg.length;
// }
//使用聯(lián)合類型決定arg是什么類型蚌成,但是不是特別好,
//如果我們有個(gè)對(duì)象凛捏,里面有個(gè)lenth的屬性笑陈,
//其實(shí)也可以調(diào)用這個(gè)方法arg: string | any[] | {length : number},
//所以很難在這里把所有的類型窮舉完,
//這個(gè)時(shí)候就不要把類型寫死葵袭,使用泛型涵妥。
interface ILength {
length: number;
}
function getLength<T extends ILength>(arg: T) {
return arg.length;
}
getLength("abc");
getLength(["abc", "cba"]);
getLength({ length: 100 });
export {};