考虑可重用性,使用泛型不仅能够支持当前的数据类型,同时也能支持未来的数据类型
类似类型的参数
一、泛型函数
// 泛型函数function loggingIdentity<T>(arg: T[]): T[] { //console.log(arg.length); // Array has a .length, so no more errorreturn arg;}
二、泛型类型
interface GenericIdentityFn<T> {(arg: T): T;}function identity<T>(arg: T): T {return arg;}let myIdentity: GenericIdentityFn<number> = identity;
三、泛型类
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; };// 如果泛型为字符串let stringNumeric = new GenericNumber<string>();stringNumeric.zeroValue = "";stringNumeric.add = function(x, y) { return x + y; };console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));
四、泛型约束
使用extends关键字约束
interface Lengthwise {length: number;}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);return arg;}loggingIdentity(3); // 错误,3没有lengthloggingIdentity({length: 10, value: 3}); // 正确
1、在泛型约束中使用类型参数
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"); // 可以getProperty(x, "m"); // 错误: x中没有m属性
2、在泛型里使用类类型
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;createInstance(Bee).keeper.hasMask;
