class - 创建其类型变量类实例的 TypeScript 泛型类?

标签 class typescript generics constructor

我熟悉 TypeScript 中的泛型类,其中可以使用关联的类型变量定义类,然后具有特定类型的实例可以操作和返回该类型的值。

问题:我想要一个创建类型变量实例的通用类。例如:

class Thing {
  thingProp: string;
}

class ThingOne extends Thing {
  thingOneProp: string;
}

class ThingTwo extends Thing {
  thingTwoProp: string;
}

class Maker<T extends Thing> {

  make(): T {
    return new T();
    //         ^--- " // <- "error TS2304: Cannot find name 'T'""
  }

}

let thingOneMaker = new Maker<ThingOne>();

let thingOne: ThingOne = thingOneMaker.make();

let thingTwoMaker = new Maker<ThingTwo>();

let thingTwo: ThingTwo = thingTwoMaker.make();

let thingError: ThingOne = thingTwoMaker.make();
//      ^--- "error TS2322: Type 'ThingTwo' is not assignable to type 'ThingOne'"

这似乎行得通。编译器生成代码,最后一行的错误表明 TypeScript 理解 thingTwoMaker.make() 应该返回什么类型。

但是,return new T(); 上的错误表明 TypeScript 不理解我正在尝试创建类型变量类的实例,并且生成的 JavaScript 证实了这一点:

var Maker = (function () {
    function Maker() {
    }
    Maker.prototype.make = function () {
        return new T(); // <- "error TS2304: Cannot find name 'T'"
    };
    return Maker;
}());

毫不奇怪,使用 Node.js 运行生成的 JavaScript 会产生一个 ReferenceError: T is not defined 错误。

如何创建一个泛型类,其实例可以创建类型变量类的实例? (使用 TypeScript 2.0.10 测试。)

最佳答案

不知何故,您需要为 Maker 类提供您希望它创建的类型的构造函数,以便它具有调用 new 的值.

我认为一个不错的选择是将类构造函数作为参数传递给 Maker 的构造函数。这将允许它构造该类的实例,并且它会自动推断它正在构建的类型,因此您不必再手动注释通用类型。

所以也许是这样的:

class Maker<T extends Thing> {

  private ctor: {new(): T};

  constructor(ctor: {new(): T}) {
    this.ctor = ctor;
  }

  make(): T {
    return new this.ctor();
  }
}

然后,您可以将正确的类构造函数传递给每种Maker,类型将被自动推断:

let thingOneMaker = new Maker(ThingOne);
let thingOne: ThingOne = thingOneMaker.make();

let thingTwoMaker = new Maker(ThingTwo);
let thingTwo: ThingTwo = thingTwoMaker.make();

// Still an error.
let thingError: ThingOne = thingTwoMaker.make();

Playground link.

关于class - 创建其类型变量类实例的 TypeScript 泛型类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50283260/

相关文章:

java - 没有找到适合 getAnnotation(Class<CAP#1>) 的方法

typescript - 如何使用 typings 安装 jquery

c++ - 类中的指针

java - Android 中的新类遇到问题

javascript - 如何在 Angular2 中获得 observable 的响应?

angular - 如何使用动态值将 "name"属性添加到 <mat-cell> 或 <mat-row>?

c# - 基于 C# 中给定对象类型的动态列表创建

java - Java 中的泛型方法和类型推断

c# - 如何向编译器保证泛型类型将具有某种属性?

c++ - 如何为 Product* getProductFromID(std::string) 编写方法定义;