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

如何为动态扩展用户类的函数添加JSDoc返回类型?

纯JS环境下用JSDoc标注动态继承类的返回类型

问题场景

在纯JavaScript环境中,我们需要为一个接收用户提供的类、返回继承自该类的新动态类的函数编写JSDoc,让VS Code这类支持类型提示的编辑器能同时识别:

  • 原用户类的方法
  • 动态类新增的方法

示例代码如下:

/**
 * Build a new class that extends the UserProvidedClass, and return that.
 * @param {class} UserProvidedClass
 * @returns ???
 */
function createClientClass(UserProvidedClass) {
  return class ClientClass extends UserProvidedClass {
    bindServerSocket(socket) {
      this.server = socket;
      this.onConnect();
    }
    onConnect() {
      super.onConnect?.();
      if (DEBUG) console.log(`client connected`);
    }  
  };
}

// 使用示例
class CustomClass {
  testServer() {
    console.log(`instance has server:`, !!this.server);
  }
}

const ClientClass = createClientClass(CustomClass);
const instance = new ClientClass();

// 编辑器应识别这是动态类新增的方法
instance.bindServerSocket(new WebSocket(`ws://localhost:800`));
// 编辑器应识别这是原CustomClass的方法
instance.testServer();

之前尝试的无效写法:

  • 直接标注返回UserProvidedClass:丢失动态类新增的方法提示
  • 提取基类:受限于JS不支持多继承,无法同时关联两类方法
  • 简单使用JSDoc泛型:仅能识别动态类新增方法,无法识别原类方法

可行解决方案

通过JSDoc泛型+交叉类型实现完整的类型提示,无需额外编写空代码:

步骤1:定义动态类新增方法的类型

先通过@typedef描述动态类添加的所有方法:

/**
 * @typedef {Object} ClientClassMixin
 * @property {(socket: WebSocket) => void} bindServerSocket - 绑定服务端socket的方法
 * @property {() => void} onConnect - 连接触发的回调方法
 */

步骤2:为函数添加泛型与交叉类型标注

修改createClientClass的JSDoc,用泛型捕获用户类的实例类型,再通过交叉类型合并原类与新增方法的类型:

/**
 * Build a new class that extends the UserProvidedClass, and return that.
 * @template T
 * @param {new () => T} UserProvidedClass - 用户提供的基类构造函数
 * @returns {new () => T & ClientClassMixin} 返回继承自基类并包含新增方法的类构造函数
 */
function createClientClass(UserProvidedClass) {
  return class ClientClass extends UserProvidedClass {
    bindServerSocket(socket) {
      this.server = socket;
      this.onConnect();
    }
    onConnect() {
      super.onConnect?.();
      if (DEBUG) console.log(`client connected`);
    }  
  };
}

效果说明

  • @template T:声明一个泛型类型T,用于捕获用户传入类的实例类型
  • new () => T:表示参数是能生成T类型实例的构造函数
  • T & ClientClassMixin:交叉类型,合并原类实例类型与新增方法的类型
  • new () => T & ClientClassMixin:表示返回的构造函数能生成同时具备两类方法的实例

此时VS Code等编辑器会正确识别:

  • instance.bindServerSocket和instance.onConnect来自动态类
  • instance.testServer来自原CustomClass

内容的提问来源于stack exchange,提问作者Mike 'Pomax' Kamermans

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:41:06