Typescript中将类的实例存储在变量中

huangapple go评论70阅读模式
英文:

Typescript instance of a class in variable

问题

我正在尝试在TypeScript中创建一个函数,该函数以一个类作为参数(不是实例,而是类本身),并返回该类的一个实例,但找不到有效的方法来实现这一点。

以下是代码示例:

public getService<T extends new (appInstances: AppInstances) => Y, Y extends AbstractService>(serviceClass: T) {
    const service = this.services.find(
      (service) => (service as unknown) instanceof serviceClass
    );
    if (!service) {
      throw new Error(
        'instance of service ' + serviceClass.name + ' not found'
      );
    }
    return service as unknown as Y;
}

// 此处的类型是任意的,应该是CommandInteractionService
const commandInteractionService = this.getAppInstances().serviceManager.getService(CommandInteractionService);

是否有适当的方法来实现这一目标,或者是否有一种解决方法?

英文:

I'm trying to create in TypeScript a function that takes a class as an argument (not an instance but the class itself) and returns an instance of that class, but can't find an effective way to do it.

Code example below:

public getService&lt;T extends new (appInstances: AppInstances) =&gt; Y, Y extends AbstractService&gt;(serviceClass: T) {
    const service = this.services.find(
      (service) =&gt; (service as unknown) instanceof serviceClass
    );
    if (!service) {
      throw new Error(
        &#39;instance of service &#39; + serviceClass.name + &#39; not found&#39;
      );
    }
    return (service as unknown) as Y;
}

// type here is any and should be CommandInteractionService
const commandInteractionService = this.getAppInstances().serviceManager.getService(CommandInteractionService);

Is there a proper way to achieve this, or is there a workaround?

答案1

得分: 0

public getService&lt;T extends new (...args: any[]) =&gt; Y, Y&gt;(serviceClass: T): Y {
  const service = this.services.find((service) =&gt; service instanceof serviceClass);
  if (!service) {
    throw new Error('找不到服务实例:' + serviceClass.name);
  }
  return service as Y;
}
英文:

something like this?

public getService&lt;T extends new (...args: any[]) =&gt; Y, Y&gt;(serviceClass: T): Y {
  const service = this.services.find((service) =&gt; service instanceof serviceClass);
  if (!service) {
    throw new Error(&#39;Instance of service &#39; + serviceClass.name + &#39; not found&#39;);
  }
  return service as Y;
}

答案2

得分: 0

我刚刚找到了解决方案,我在这里发布它,因为找到它并不容易。希望将来绝望的人能找到这个有用。

public getService<T extends new (...args: ConstructorParameters<typeof AbstractService>) => AbstractService>(serviceClass: T): InstanceType<T> {
  const service = this.services.find(
    (service) => service instanceof serviceClass,
  );
  if (!service || serviceClass === AbstractService) {
    throw new Error(
      '未找到服务的实例:' + serviceClass.name,
    );
  }
  return service as InstanceType<T>;
}

您可以在官方 TypeScript 文档 https://www.typescriptlang.org/docs/handbook/utility-types.html 上找到关于 InstanceTypeConstructorParameters 的文档。

英文:

edit

I just found the solution, I am posting it here since it wasn't easy to find. Hoping that future desperate souls find this useful.

public getService&lt;T extends new (...args: ConstructorParameters&lt;typeof AbstractService&gt;) =&gt; AbstractService&gt;(serviceClass: T): InstanceType&lt;T&gt; {
  const service = this.services.find(
    (service) =&gt; service instanceof serviceClass,
  );
  if (!service || serviceClass === AbstractService) {
    throw new Error(
      &#39;instance of service &#39; + serviceClass.name + &#39; not found&#39;,
    );
  }
  return service as InstanceType&lt;T&gt;;
}

You can find documentation about InstanceType and ConstructorParameters on the official TypeScript documentation https://www.typescriptlang.org/docs/handbook/utility-types.html

huangapple
  • 本文由 发表于 2023年7月7日 03:32:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632029.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定