将类型作为参数进行传递,通过参数传递解决代码复用问题。
泛型类
/* 普通类 */
// 相同的逻辑,参数需要不同的类型,需要定义三个函数
class StringKeyValuePair {
constructor(public key: string, public value: string) { }
};
class NumberKeyValuePair {
constructor(public key: number, public value: number) { }
};
class StringNumberKeyValuePair {
constructor(public key: string, public value: number) { }
};
// 语法格式
class 类名<参数1类型, 参数2类型> {
constructor(修饰符 参数名: 参数1类型, 修饰符 参数名: 参数2类型) {};
};
/* 泛型类 */
// 将参数类型进行传递,解决代码复用问题
class keyValuePair<T, V> {
constructor(public key: T, public value: V) { }
};
const k1 = keyValuePair<string, number>("a", 1);
const k2 = keyValuePair<number, number>(10, 10);
泛型函数
// 普通函数
function getStringValue(value: string): string {
return value;
};
function getNumberValue(value: number): number {
return value;
};
function getBooleanValue(value: boolean): boolean {
return value;
};
// 语法格式
function 方法名<T>(参数名: 参数1类型): 返回值类型 { };
// 泛型函数
function getValue<T>(value: T): T {
return value;
};
// 需要什么类型,就传什么类型,T就是什么类型
const v1 = getValue<string>("a");
const v2 = getValue<number>(10);
const v3 = getValue<boolean>(true);
泛型接口
需求:定义一个 fetch 方法用于获取数据,设置 fetch 方法的返回值的类型。
- 通过 fetch 方法获取 user,fetch 方法的返回值类型就是 user;
- 通过 fetch 方法获取 product,fetch 方法的返回值类型就是 product;
// 类型接口 interface User { username: string; }; interface Product { title: string; }; // 返回值接口 interface Result<T> { data: T | null; error: string | null; }; function fetch<T>(): Result<T> { return { data: null, error: null }; }; // 传递不同的类型,返回相应的数据 fetch<User>().data?.username; fetch<Product>().data?.title;
泛型约束
对泛型参数的范围进行约束,限制能够传递的类型范围。
class StringOrNumberArray<T extends string | number> {
constructor(public collection: T[]) {
get(index: number): T {
return this.collection[index];
};
};
};
new StringOrNumberArray<string>(["a", "b"]);
new StringOrNumberArray<number>([10, 20]);
// 不需要传递布尔类型的数组,需要通过泛型的类型进行约束
// new StringOrNumberArray<boolean>([true, false]);
-
约束是接口
interface Person { name: string; }; function echo<T extends Person>(value: T): T { return value; }; // 约束是接口,需要传递接口对象 echo({name: "张三"});
-
约束是类
class Person { constructor(public name: string) {} }; function echo<T extends Person>(value: T): T { return value; }; // 约束是类,需要传递类的实例 echo( new Person("张三") );
继承泛型类
class Product {
name: string;
price: number;
};
class Store<T> {
protected _objects: T[] = [];
add(obj: T) {
this._objects.push(obj);
};
};
const store = new Store<Product>();
// 继承一个泛型类T,在new创建实例的时候定义这个类
class CompressibleStore<T> extends<T> { };
new CompressibleStore<Product>();