泛型创建可重用的组件

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

 

posted on 2019-05-29 15:39  旧梦丶  阅读(150)  评论(0编辑  收藏  举报