如何用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
相关产品推荐
相关产品推荐

