泛型创建可重用的组件
function identity(arg: any): any { return arg + '' //如果我们这样写传入了一个number,返回值类型将不是number //我们需要一种手段来约束传的值和返回值的类型 }
function identity<T>(arg: T): T { // return arg + ''//我们定义一个泛型类型T再这样写将会报错 return arg } //第一种使用方法 let output = identity<string>('myString') //第二种使用方法,依靠类型推断 let output1 = identity('myString')
function loginIdentity<T>(arg: T): T{ //console.log(arg.length)//这句话将报错,因为这个T是任意类型 return arg } //可以这样修改T类型的数组 function loginIdentity1<T>(arg: T[]): T[]{ console.log(arg.length) return arg }
泛型变量
泛型接口
function identity<T>(arg: T): T { return arg } let myIdentity: <T>(arg: T) => T = identity //也可以这样写 interface GenericIdentityFn { <T>(arg: T): T } let myIdentity1: GenericIdentityFn = identity //把里面定义的T拿出来,这样我们传入函数的时候必须指定泛型类型,不必在函数里面指定 //推荐这种写法 interface GenericIdentityFn1<T> { (arg: T): T } let myIdentity2: GenericIdentityFn1<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'))//test
泛型约束
回顾因为any类型,所以打印arg.length出错的函数,当时的解决方法是把泛型指定为数组
//我们可以给泛型加类型约束 interface Lengthwise { length: number } function loginIdentity<T extends Lengthwise>(arg: T): T{ console.log(arg.length)//2 return arg } loginIdentity({length: 2})
function getProperty<T, K extends keyof T>(obj: T, key: K) { return obj[key] } //上述函数约束K的泛型约束与T的key 值 let x = {a: 1, b: 2, c: 3, d: 4} getProperty(x, 'a') //getProperty(x, 'm')//报错,上述x没有key值为m的参数
在泛型中使用类类型
//工厂函数的构造器 function create<T>(c: { new(): T}): T { return new c() }
class BeeKeeper { hasMask: boolean } class LionKeeper { nametag: string } class Animal { numLengs: number } class Bee extends Animal { keeper: BeeKeeper } class Lion extends Animal { keeper: LionKeeper } //创建一个类类型 function createInstance<T extends Animal>(c: new()=>T) { return new c() } createInstance(Lion).keeper.nametag createInstance(Bee).keeper.hasMask
编译后
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var BeeKeeper = /** @class */ (function () { function BeeKeeper() { } return BeeKeeper; }()); var LionKeeper = /** @class */ (function () { function LionKeeper() { } return LionKeeper; }()); var Animal = /** @class */ (function () { function Animal() { } return Animal; }()); var Bee = /** @class */ (function (_super) { __extends(Bee, _super); function Bee() { return _super !== null && _super.apply(this, arguments) || this; } return Bee; }(Animal)); var Lion = /** @class */ (function (_super) { __extends(Lion, _super); function Lion() { return _super !== null && _super.apply(this, arguments) || this; } return Lion; }(Animal)); //创建一个类类型 function createInstance(c) { return new c(); } createInstance(Lion).keeper.nametag; createInstance(Bee).keeper.hasMask;
2019-05-29 15:38:24
工欲善其事,必先利其器