打字稿泛型:引用类而不是实例

时间:2019-09-24 08:00:38

标签: typescript generics

我遇到了要在一组接口中使用泛型的情况。我的公共接口接收通用类型,并将其向下传递到未导出的专用接口。在我的公共界面中,我想使用通用类型T,但我不要希望它引用T instance 。我想说的是可以生成T实例的类T

尝试此操作,出现错误:

interface Car<T> {
  unit: T;
  progress: number;
}

export interface CarFactory<T> {
  cars: Car<T>[];
  // Type error: 'T' only refers to a type, but is being used as a value here.  TS2693
  blueprint: typeof T;
}

使用生成器功能有效。但是然后我必须将其传递下去,并公开我的代码的更多内部信息,这是我想避免的。

interface CarFactory<T> {
  blueprint: (args: any) => T;
}

我不能直接使用T,因为这会使编译器认为它应该接收T的实例,而不是类。这会触发TS2740错误。使用T = CarModelT['constructor']作为blueprint类型有效,但前提是我必须像这样修补类:

class CarModel {
  public ['constructor']: typeof CarModel;
}

所以问题是:如何使用这样的泛型?是否同时使用T和实际T的两个实例?生成器函数或带有修补后的['constructor']的{​​{1}}是我唯一的选择吗?我是否需要传递另一个与T相似的通用类型U

2 个答案:

答案 0 :(得分:1)

你的意思是这样吗?

给定类Car的{​​{3}}(引用类的构造函数的符号Car)将为typeof Car。在CarFactory界面中,我们没有一些具体的类,因此我们可以将new (...args: any) => T的{​​{3}} blueprint用作:

export interface CarFactory<T> {
  cars: Car<T>[];
  // use a constructor function type here
  blueprint: new (...args: any) => T;
}

测试:

class CombiUnit {
  // your implementation of a car unit/model T goes here
}

type CombiUnitFactory = CarFactory<CombiUnit>;

// new (...args: any) => CombiUnit
type CombiUnitFactoryCtorFunction = CombiUnitFactory["blueprint"];

// some concrete factory
declare const t1: CombiUnitFactory;

const result = new t1.blueprint(); // const result: CombiUnit

type of the class itself

答案 1 :(得分:0)

typeof 运算符有效地返回一个值。编写

interface Car<T> {
  blueprint: T;
}

除此之外,我认为工厂类应该是静态的,因此不需要接口。您可以改成这样的静态汽车工厂类:

export class AutomobileFactory {
  static createCar<T>(): Car<T> {
    // create a concrete car implementation of the
    // generic type T instead of throwing an error
    throw new Error("Not implemented");
  }
}