要求 class 以基于泛型的参数实现方法

Require class to implement method with params based on generics

我有一个 Class装饰器,它采用未指定数量的构造函数参数 (<T>: { new (...args: any[]) => T }) 并且基于此我希望 class 需要实现一个方法,该方法的参数反映了这些提供的构造函数的类型。

我的装饰师:

type Constructor<T> = new (...args: any[]) => T;
type ComponentArray = Array<Constructor<unknown>>;

export interface TSystem<TComps extends ComponentArray> {
  handle: (...comps: TComps) => void;
}


export function System<TComps extends ComponentArray>(...comps: TComps) {
  return (ctor: Constructor<Required<TSystem<TComps>>>) => {
     // add metadata etc...
  };
}

示例:


class RandomComponent {
  test1: string;
  // implementation ...
}

class RandomComponent2 {
  test2: string;
  // implementation ...
}

@System(RandomComponent, RandomComponent2 /* etc ... */)
class TestSystem {
  handle(r1: RandomComponent, r2: RandomComponent2 /* etc... */) {
    // handle components ...
  }
}

我希望这会起作用,但是编译器给我这个错误:

Type '(comp: RandomComponent) => void' is not assignable 
to type '(comps_0: typeof RandomComponent) => void' 

有没有一种方法可以从 TSystem 接口中删除 typeof 或以不同的方式完成此操作?我想访问 Class 的实例而不是它的类型。或者这只是 TypeScript 类型系统的限制?

该代码适用于我的 3.5.1 我将 post 放在这里,您能否更新您的问题并指出错误所在,我会更新我的答案。您所描述的肯定 is 可以使用 Typescript。

https://typescript-play.js.org/?experimentalDecorators=true#code/C4TwDgpgBAwg9gOwM7AE4FcDGw6oDwAqAfFALxQIQDuUAFAHSMCGqA5kgFxRMIgDaAXQCUZEgQDcAKFCRYcALZhEEBMACCqVExBkoGrSDzoEAawRwqCIlMkQAHktTAoAS1URUAMyaZoBAMogKBDyhPCKSFD2wCoAJpHhSpSq+tokAN6SUFAAFjyxADYQXAyMmApgnFAEiUgipCQAbnAusVIAvpJd9o7OnsbYLohQgcGhNRWR0XEJFcopmmml9OURXBMRIpnZqBDA6KgIdNi4XPDIaFg4+ABKEACO6C67sYSjMeO1RN-1GVnZ2QA9IDuLFYlB5HsmLEmMAmFFgJhGPR-u0Ol1MAUmEhIjd8gpEvNnNsoMC5Ioia5FEVIapYUMEJJOpIAALvEK0PEIWIEubJYBCSSY7GRAgQFDs+RQEl5blFWirMBcLk8+SE-lbUkgqi4ExIf5AkHIqKxFzORWoplAA

编辑: 更改此行

  handle(comp: typeof RandomComponent) 

我很确定应该按照您的要求让我知道。

EDIT2:我想这就是你想要的。

type Constructor<T> = new (...args: any[]) => T;
type ComponentArray = Array<Constructor<unknown>>;

export interface TSystem<TComps extends ComponentArray> {
  handle: (...comps: ConvertInstanceTypes<TComps>) => void;
}

type ConvertInstanceTypes<T extends any[]> = {
  [K in keyof T]: T[K] extends Constructor<any> ? InstanceType<T[K]> : never;
}


export function System<TComps extends ComponentArray>(...comps: TComps) {
  return (ctor: Constructor<Required<TSystem<TComps>>>) => {
     // add metadata etc...
  };
}

class RandomComponent {
  test1: string = "test1";
  // implementation ...
}

class RandomComponent2 {
  test2: string = "test2";
  // implementation ...
}


@System(RandomComponent, RandomComponent2)
class TestSystem {
  handle(r1: InstanceType<typeof RandomComponent>, r2: InstanceType<typeof RandomComponent2>) {
    // handle components ...
  }
}