一. 泛型基础
1. 泛型函数
定义
function identity<T>(arg: T): T {
return arg;
}
使用
(使用时应注意,泛型应被当做可能的所有类型,例如number不会存在length属性)
// 传入类型参数
(1) let str: string = identity<string>('hhh');
// 不传入类型参数,即使用类型推论,编译器会自动完成类型的推断;
// 但是在复杂情况下,编译器不能推断出类型,所以只能采取第一种方法
(2) let str: string = identity('hhh');
二. 泛型接口
以下,泛型接口描述函数
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
三.泛型类
泛型类定义同样是在类后加泛型类型参数T,这个T可以是任意的类型,只要符合要求
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
四.泛型约束
泛型约束就是为泛型本身定义一些约束条件
下面例子中T继承了接口Lengthwise(T extends Lengthwise),而Lengthwise具有length属性,这样在使用T的时候,就可以放心的使用length属性了
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 error
return arg;
}
在泛型约束中使用类型参数
声明一个类型参数,他被另一个类型参数所约束,如下面的例子:
// 一个类型参数K被另一个类型参数T约束,K必须在T的对象属性上
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a"); // okay
getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.
五.在泛型里使用类类型
此用法没有弄懂...
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a"); // okay
getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.