简体   繁体   English

TypeScript泛型类,它创建类型变量类的实例?

[英]TypeScript generic class that creates instances of its type variable's class?

I'm familiar with generic classes in TypeScript, where a class can be defined with an associated type variable, and then instances with a specific type can manipulate and return values of that type. 我熟悉TypeScript中的泛型类,其中可以使用关联的类型变量定义类,然后具有特定类型的实例可以操作并返回该类型的值。

Problem: I want a generic class that creates instances of the type variable. 问题:我想要一个创建类型变量实例的泛型类。 For instance: 例如:

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'"

This almost seems to work. 这几乎似乎有效。 The compiler generates code, and the error on the last line shows that TypeScript understands what type thingTwoMaker.make() should return. 编译器生成代码,最后一行的错误表明TypeScript了解thingTwoMaker.make()应返回的类型。

However, the error on return new T(); 但是, return new T();出错return new T(); shows that TypeScript doesn't understand that I'm trying to make instances of the type variable's class, and the generated JavaScript confirms it: 表明TypeScript不理解我正在尝试创建类型变量的类的实例,并且生成的JavaScript确认它:

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

And, not surprisingly, running the generated JavaScript with Node.js produces a ReferenceError: T is not defined error. 并且,毫不奇怪,使用Node.js运行生成的JavaScript会产生ReferenceError: T is not defined错误。

How can I make a generic class whose instances can create instances of the type variable class? 如何创建一个泛型类,其实例可以创建类型变量类的实例? (Tested using TypeScript 2.0.10.) (使用TypeScript 2.0.10测试。)

Somehow, you need to give the Maker class the constructor of the type you'd like it to make, so that it has a value on which to call new . 不知何故,你需要为Maker类提供你想要它的类型的构造函数,以便它有一个值来调用new

I'd say a good option would be to pass the class constructor as an argument to Maker 's constructor. 我想说一个好的选择是将类构造函数作为参数传递给Maker的构造函数。 That will allow it to construct instances of that class, and it will automatically infer the type that it's building so you don't have to manually annotate the generic type anymore. 这将允许它构造该类的实例,并且它将自动推断它正在构建的类型,因此您不必再手动注释泛型类型。

So maybe something like this: 也许是这样的:

class Maker<T extends Thing> {

  private ctor: {new(): T};

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

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

Then, you can pass the right class constructor to each kind of Maker , and the type will be automatically inferred: 然后,您可以将正确的类构造函数传递给每种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. 游乐场链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM