作用:创建可重用的组件,一个组件支持多种类型的数据。
// 类型变量Tfunction identity<T>(arg: T): T {return arg;}
定义泛型函数有两种使用方法:
- let a = indetity
(‘myString’); // 明确T是string类型,并做为一个参数传给函数 - let a = indetity(‘myString’); // 普遍,类型推论
6.2 使用泛型变量
// 泛型给定什么类型就需要什么类型checkboxBarBtns: LqGridActionBtn<object>[] = [{text: '批量审核',onclick: async (data) => {this.dialogService.Confirm({title: '批量审核',content: '是否执行批量审核?',onOk: async () => { },onCancel: () => { }});}}];
function loggingIdentity<T>(arg: T): T {console.log(arg.length); // Error: T doesn't have .lengthreturn arg;}
function loggingIdentity<T>(arg: T[]): T[] {// 并不清楚T的类型是啥,T是[]是可以的console.log(arg.length); // Array has a .length, so no more errorreturn arg;}
这些类型变量代表的是任意类型,所以有可能传入数字,数字没有.length属性,所以报错。
可以将它当作一个数组操作。
6.3 范型类型
泛型函数的类型和非泛型函数的类型没什么不同,区别是 泛型函数有一个参数在最前面,像函数声明一样。
function identity<T>(arg: T): T {return arg;}let myIdentity: <U>(arg: U) => U = identity;
- 可定义不同的泛型参数名,只需要数量上和使用方式上对应上就可以。
- 可以使用带有调用签名的对象字面量来定义泛型函数,还可指定类型
```typescript
interface GenericIdentityFn {
(arg: T): T; }
function identity
let myIdentity: GenericIdentityFn = identity;
```typescriptinterface GenericIdentityFn<T> {(arg: T): T; // 非泛型函数}function identity<T>(arg: T): T {return arg;}let myIdentity: GenericIdentityFn<number> = identity;
6.4 泛型约束:使用接口和extends关键字实现约束。
interface Lengthwise {length: number; // 必须包含此属性}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length); // Now we know it has a .length property, so no more errorreturn arg;}loggingIdentity(3); // Error, number doesn't have a .length propertyloggingIdentity({length: 10, value: 3}); // OK,需要传入符合约束类型的值,必须包含必须属性
在泛型约束中使用类型参数
function getProperty(obj: T, key: K) {return obj[key];}let x = { a: 1, b: 2, c: 3, d: 4 };getProperty(x, "a"); // okaygetProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.
在泛型里使用类类型:
