什么是泛型
设计泛型的关键目的是在成员之间提供有意义的约束,这些成员可以是:类的实例成员、类的方法、函数参数和函数返回值。
泛型变量之间可以约束
泛型的类型可以有多个,并且类型变量之间还可以约束(比如第二个类型变量受第一个类型变量约束)。
比如创建一个函数来获取对象中属性的值:
function group<type, Key extends keyof type>(obj: type, key: Key) {
return obj[key];
}
group({ name: "赵四", age: 18 }, "name");
group({ name: "赵四", age: 18 }, "age");
//错误演示
// group({ name: "赵四", age: 18 }, "sex");//会报错 sex 不是type中的属性
解释:
- 添加了第二个变量Key,两个类型之间使用(,)
逗号进行分割。 keyof关键字接收一个对象类型,生成其键名称(可能是字符串或数字)的联合类型。- 在这个示例中 keyof Type 实际上获取的是对象中的"name"|"age"
类型变量Key受Type约束,可以理解为:Key只能是Type所有键中的任意一个,或者说只能访问对象中存在的属性。
泛型接口:
泛型接口可以配合泛型来使用,以增加其灵活性,增强复用性。
interface IdFunc<T> {
id: (value: T) => T;
ids: () => T[];
}
//必须要指定类型 这里我们先指定类型为 number
let obj: IdFunc<number> = {
id(value) {
return value;
},
ids() {
return [1, 2, 3];
}
};
解释:
- 在接口名称的后面添加
<类型变量>,那么,这个接口就变成了泛型接口。 - 在接口的类型变量,对接口中所有其他成员剋见,也就是接口中说
所有成员都可以使用类型变量。 - 使用泛型接口时,需要指定具体的类型(比如,此处的
IdFun<number>) - 此时,id方法的参数和返回值类型都是 number;ids方法的返回值是 number[].