Typescript 泛型:引用类而不是实例

kla*_*son 5 generics typescript

我遇到了一种情况,我想在一组接口中使用泛型类型。我的公共接口接收通用类型并将其传递给非导出的私有接口。在我的公共接口中,我想使用泛型类型T,但我希望它引用的实例T。我想让它说它是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;
}
Run Code Online (Sandbox Code Playgroud)

使用生成器函数是可行的。但随后我必须将其传递下去并暴露更多代码的内部结构,这是我想避免的。

interface CarFactory<T> {
  blueprint: (args: any) => T;
}
Run Code Online (Sandbox Code Playgroud)

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

class CarModel {
  public ['constructor']: typeof CarModel;
}
Run Code Online (Sandbox Code Playgroud)

所以问题是:我如何使用这样的泛型?使用 的实例T和实际的T? 生成器功能或['constructor']修补程序是T我唯一的选择吗?我是否需要传递另一种U类似于 的泛型类型U = typeof T

for*_*d04 1

你的意思是这样的吗?

给定一个类,该类本身的类型Car(引用该类构造函数的符号)将为。在接口中,我们没有具体的类,因此我们可以使用构造函数的类型:Cartypeof CarCarFactory new (...args: any) => Tblueprint

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

测试一下:

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
Run Code Online (Sandbox Code Playgroud)

操场