泛型
泛型指使用时才定义类型,即定义可以像参数一样定义,主要解决类,接口、函数的复用性,让他们可以处理多种类型。
基本使用
下面的示例返回值是 any,这不是我们想要的,因为我们想要具体返回类型
ts
function dump(arg: any) {
return arg;
}
dump(1);
dump("hello");
使用了泛型定义后,返回值即为明确了类型
ts
function dump<T>(arg: T) {
return arg;
}
dump<string>("hello");
如果调用时不指定类型系统也会自动推断类型
ts
dump("hello"); // string
dump(1); // number
类型继承
下面的代码是不严谨的,我们不需要处理数字,因为数字没有 length 属性,同时我们希望返回的类型不是 any
ts
function getLength(arr: any) {
return arr.length;
}
getLength([1, 2, 3]); // 3
getLength("hello"); // 5
getLength(1); // undefined
泛型为不确定类型,所以下面没有 length 属性将会报错
ts
function getLength<T>(arr: T[]): number {
return arr.length;
}
我们可以继承来解决这个问题
ts
function getLength<T extends { length: number }>(arr: T): number {
return arr.length;
}
// 或者结合 interface 或 type
type LengthType = {
length: number;
};
function getLength<T extends LengthType>(arr: T): number {
return arr.length;
}
类
下面我们来掌握在类中使用泛型的方法
使用泛型复用类
ts
class User<T> {
constructor(private user: T) {}
get(): T {
return this.user;
}
}
type T = {
name: string;
age: number;
};
const user = new User<T>({ name: "John", age: 20 });
接口
下面是接口的类型使用泛型
ts
interface ArticleInterface<T, B> {
comment: T;
title: B;
}
class Article<T, B> {
comment: T;
title: B;
constructor(params: ArticleInterface<T, B>) {
this.comment = params.comment;
this.title = params.title;
}
get() {
return { comment: this.comment, title: this.title };
}
}
const article = new Article<string, number>({ comment: "hello", title: 1 });