1.认识泛型
我们为了让这个sum函数,他具备通用性,我这里得写一大堆的联合类型
而且对于这一大堆的联合类型来说,他们还有一些共性,还有哪些共性呢,比如说如果我们是一个number类型和这个string类型的话,他们是可以相加的,如果是我们后面这两种类型的话,它是可以获取的length的,但是当我们把这些所有的这些类型写到一起的时候在这里做一些操作的时候,其实我们就需要一个一个对他们来做判断了,因为我们这里这个number一样,你看我把鼠标放上来的时候,这个NUMBER它就可能是四种类型里面的其中一个,我哪知道你是什么类型,根本就不知道,你只能在这里慢慢给他做一些判断了。
在我们定义一个函数的时候,除了我们的这个参数的值可以让外界在调用的时候动态决定之外,我们的这个参数的类型也应该是可以让外界来决定的。js没有类型,但是ts有类型限制,一般写一个固定的类型的,才会有类型限制。
解决方法要把我们的类型进行参数化,什么叫做类型参数化呢,意思是我这里到底是一个什么类型,不是我在定义函数的时候决定定义的,在我们定义这个函数时,我不决定这些参数的类型,而是让调用者以参数的形式告知我这里的函数参数应该是什么类型。
2.泛型实现类型参数化
// 类型的参数化
// 在定义这个函数时, 我不决定这些参数的类型
// 而是让调用者以参数的形式告知,我这里的函数参数应该是什么类型
function sum<Type>(num: Type): Type {
return num
}
// 1.调用方式一: 明确的传入类型
sum<number>(20)
sum<{name: string}>({name: "why"})
sum<any[]>(["abc"])
// 2.调用方式二: 类型推到
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.泛型的基本补充
4.泛型接口
interface IPerson<T1, T2> {
name: T1;
age: T2;
}
const p: IPerson<string, number> = {
name: "why",
age: 18,
};
export {};
或者给IPerson一个默认类型
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,而是字符串呢?这时候不应该把类的类型写死
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;
// }
//使用联合类型决定arg是什么类型,但是不是特别好,
//如果我们有个对象,里面有个lenth的属性,
//其实也可以调用这个方法arg: string | any[] | {length : number},
//所以很难在这里把所有的类型穷举完,
//这个时候就不要把类型写死,使用泛型。
interface ILength {
length: number;
}
function getLength<T extends ILength>(arg: T) {
return arg.length;
}
getLength("abc");
getLength(["abc", "cba"]);
getLength({ length: 100 });
export {};