You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JSDoc泛型类型表示类的实例类型

给服务工厂方法添加正确的JSDoc注解以推断返回类型

我写了一个用来减少重复堆分配的JavaScript服务工厂,核心方法代码如下:

/**
 * @param {class} cls 
 */
getService(cls) {
  let service = this._services.get(cls); // this._services 是一个 Map
  if(!service) {
    service = Reflect.construct(cls);
    this._services.set(cls, service);
  }
  return service;
}

调用方式是:

const service = ServiceFactory.getInstance().getService(SomeServiceType)

我希望通过JSDoc注解让编辑器能准确识别service的类型(也就是SomeServiceType的实例),但之前尝试的@template写法没生效,比如:

/**
 * @template T
 * @param {class<T>} cls 
 * @returns {T}
 */
getService(cls) {
  let service = this._services.get(cls);
  if(!service) {
    service = Reflect.construct(cls);
    this._services.set(cls, service);
  }
  return service;
}

正确的JSDoc写法

问题出在构造函数的类型标注上,JSDoc里需要用{new () => T}来表示能构造出T类型实例的构造函数,而不是class<T>。修改后的注解如下:

/**
 * @template T
 * @param {new () => T} cls - 要获取单例实例的服务类
 * @returns {T} 返回该类的单例实例
 */
getService(cls) {
  let service = this._services.get(cls);
  if(!service) {
    service = Reflect.construct(cls);
    this._services.set(cls, service);
  }
  return service;
}

为什么这样有效

new () => T是JSDoc(以及TypeScript)中标准的构造函数类型表示法:

  • new关键字表示这是一个可以被new调用(或者通过Reflect.construct调用)的构造函数
  • ()表示该构造函数接受无参(如果你的服务类有参数,可以改成new (...args: any[]) => T或者更具体的参数类型)
  • => T表示调用这个构造函数会返回T类型的实例

这样修改后,编辑器(比如VS Code)就能正确推断出getService(SomeServiceType)返回的是SomeServiceType的实例,代码补全和类型检查都能正常工作。

内容的提问来源于stack exchange,提问作者Jason Polites

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:18:18