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

能否使用JSDoc标注策略模式类工厂与链式API结构?

问题:如何用JSDoc标注动态继承的链式API结构?

我有这样的继承链:Chainable -> Strategy -> Actions,调用端通过Actions使用链式API:

await actionMaker()
  .action1()
  .action2()
  .run();

其中run方法来自Chainable,action1和action2可来自Strategy或Actions。动作方法会被推入数组,run通过Promise执行所有动作。实际代码结构如下:

// Chainable:
class Chainable {
  enqueue(fn) { this.queue.push(fn); return this; }
  run() { return Promise_that_runs_everything; }
}

// Strategies:
class platformStrategy1 extends Chainable {
  action1() {
    return this.enqueue(() => {
      /* action1 implementation for platform 1 */ 
    }) 
  }
}

class platformStrategy2 extends Chainable {
  action1() {
    return this.enqueue(() => {
      /* action1 implementation for platform 2 */ 
    }) 
  }
}

// Actions:
function actionMaker(strategy) {
  class _Action extends strategy {
    action2() { return this.action1(); }
  }
  return new _Action();
}

// Call site:
await actionMaker(platformStrategy1)
  .action1()
  .action2()
  .run();

我可以根据运行平台传入不同策略,不同平台对应不同的动作实现。Actions中的方法仅调用Strategy的方法,策略类持有具体实现细节。除run返回执行动作的Promise外,所有方法均返回this。由于无法使用TypeScript,想询问:能否使用JSDoc对这类结构进行标注?


回答

当然可以用JSDoc标注这类动态继承的链式结构,下面是具体的标注方案,能让编辑器正确识别类型和链式调用提示:

1. 标注基类Chainable

/**
 * 基础链式操作类,提供队列管理和执行能力
 * @class
 */
class Chainable {
  constructor() {
    /** @type {Function[]} 动作执行队列 */
    this.queue = [];
  }

  /**
   * 将动作加入执行队列
   * @param {Function} fn 要执行的动作函数
   * @returns {this} 返回实例本身以支持链式调用
   */
  enqueue(fn) {
    this.queue.push(fn);
    return this;
  }

  /**
   * 依次执行队列中所有动作
   * @returns {Promise<void>} 返回执行完成的Promise
   */
  run() {
    return this.queue.reduce((promise, fn) => promise.then(fn), Promise.resolve());
  }
}

2. 标注策略类与接口

先定义策略的方法契约,再让具体策略实现:

/**
 * 平台策略接口,定义所有策略必须实现的方法
 * @interface
 * @extends Chainable
 */
function PlatformStrategy() {}

/**
 * 平台通用动作1
 * @returns {this} 返回实例本身以支持链式调用
 * @memberof PlatformStrategy
 */
PlatformStrategy.prototype.action1 = function() {};

/**
 * 平台1的具体策略实现
 * @class
 * @extends Chainable
 * @implements PlatformStrategy
 */
class platformStrategy1 extends Chainable {
  /**
   * @returns {this}
   */
  action1() {
    return this.enqueue(() => {
      /* 平台1的action1实现 */
    });
  }
}

/**
 * 平台2的具体策略实现
 * @class
 * @extends Chainable
 * @implements PlatformStrategy
 */
class platformStrategy2 extends Chainable {
  /**
   * @returns {this}
   */
  action1() {
    return this.enqueue(() => {
      /* 平台2的action1实现 */
    });
  }
}

3. 标注actionMaker函数

通过模板参数处理动态继承的类型,让返回值同时包含策略方法和自定义动作:

/**
 * 创建动作实例,动态继承传入的平台策略类
 * @template {typeof PlatformStrategy} T
 * @param {T} strategy 要继承的平台策略类
 * @returns {InstanceType<T> & { action2(): InstanceType<T> }} 返回继承了策略的动作实例,包含额外的action2方法
 */
function actionMaker(strategy) {
  class _Action extends strategy {
    /**
     * 自定义动作2,内部调用action1
     * @returns {this}
     */
    action2() {
      return this.action1();
    }
  }
  return new _Action();
}

4. 调用端的类型提示验证

完成标注后,编辑器会自动识别链式调用的每个方法:

/**
 * 调用示例
 */
async function demo() {
  await actionMaker(platformStrategy1)
    .action1() // 能识别来自platformStrategy1的action1
    .action2() // 能识别来自_Action的action2
    .run();    // 能识别来自Chainable的run
}

关键标注要点

  • 用@interface定义策略的方法契约,确保所有策略类实现统一方法
  • 通过@template和InstanceType处理动态继承的类型,让actionMaker返回值同时包含策略方法和自定义动作
  • 所有链式方法标注@returns {this},保证编辑器识别链式调用的类型连贯性
  • 用@implements标记具体策略类实现了策略接口,增强类型检查的严谨性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 21:50:16