在TypeScript中,泛型的作用主要是为了实现类型的约束,常见于类、接口、函数之上,它不仅可以约束基本类型,也可以约束自定义类型;
1、函数参数类型校验
如下函数,要求参数arg必须是number类型,也是对参数的一种约束
function identity(arg: number): number {
return arg;
}
2、使用泛型约束函数
如下写法要求调用identity函数的时候入参类型和出参类型必须一致,具体说明类型在调用的时候说明
function identity<T>(arg: T): T {
return arg
}
// 入参是数字,返回的参数也是数字
let num = identity(10)
console.log(typeof num); // 输出number
// 入参是字符串,返回的参数也是字符串
let str = identity('hello')
console.log(typeof str); // 输出string
3、泛型类
构建此类对象需要确定一个类型T,并且zeroValue属性的类型和new对象传入类型T一致,
add属性是一个函数,必须包含俩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; };
4、泛型约束
函数的参数类型必须具备length属性
interface Lengthwise {
length: number;
}
// 传入的参数类型必须是Lengthwise的子类
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;
}
// 正确调用
loggingIdentity({length: 10, value: 3});
5、多个泛型参数
如果有需要,可以同时约束多个参数的类型使用泛型
function getProperty(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'.
6、在泛型里使用类类型
class BeeKeeper {
hasMask: boolean;
}
class ZooKeeper {
nametag: string;
}
class Animal {
numLegs: number;
}
class Bee extends Animal {
keeper: BeeKeeper;
}
class Lion extends Animal {
keeper: ZooKeeper;
}
function createInstance<A extends Animal>(c: new () => A): A {
return new c();
}
createInstance(Lion).keeper.nametag; // typechecks!
createInstance(Bee).keeper.hasMask; // typechecks!