JSDoc如何实现泛型工厂方法正确返回指定泛型类实例
问题根因
代码里两处JSDoc标注错误直接导致类型推断不符合预期:
- 泛型基类
AbstractDataService的构造函数参数类型标注错误:泛型T代表的是数据类的实例类型,但构造函数接收的入参是类构造函数本身,不是类实例,原标注@param {T} classType类型和实际入参不匹配。 - 子类继承泛型基类时传入了错误的泛型参数:
AccountService继承AbstractDataService时原标注为@extends AbstractDataService<AccountService>,相当于告知类型检查器该服务的泛型T就是AccountService本身,getOne()自然会被推断返回AccountService类型。另外Account类上的@extends AbstractDataObject<Account>属于无效标注,因为AbstractDataObject本身未声明泛型参数。
修正后可正常运行的代码
/** * 数据库记录抽象基类 * @class */ class AbstractDataObject { constructor() {} save() {} update() {} delete() {} } /** * 数据库记录查询抽象服务类 * @class * @template T */ class AbstractDataService { /** * @param {new() => T} classType 数据类构造函数 */ constructor (classType) { this.classType = classType } /** * @returns {T} 对应数据类的新实例 */ getOne () { return new this.classType() } } /** * 账户数据类 * @class * @extends {AbstractDataObject} */ class Account extends AbstractDataObject { constructor () { super () } } /** * 账户查询服务类 * @class * @extends {AbstractDataService<Account>} */ class AccountService extends AbstractDataService { constructor () { super (Account) } } const accountService = new AccountService() const account = accountService.getOne() // 此处输入account. 即可正常提示save()、update()、delete()等成员方法
关键修正说明
- 将构造函数
classType参数的类型从{T}修改为{new() => T}:这是JSDoc中表示「无参构造函数、返回T类型实例」的标准写法,类型检查器可正确识别new this.classType()的返回值为T类型。 - 将
AccountService的继承标注从@extends AbstractDataService<AccountService>修改为@extends {AbstractDataService<Account>},明确指定泛型T的实际类型为Account实例。 - 移除
Account类上错误的泛型参数传递,直接标注继承自AbstractDataObject即可。
内容的提问来源于stack exchange,提问作者Tom Nijs
相关产品推荐
相关产品推荐

