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

TypeScript实现@End装饰器 强制链式调用末尾必须执行run方法

方案1:类型约束强制必须调用run(),漏写直接编译报错

TypeScript 本身的装饰器仅负责运行时逻辑,没有原生支持类似 Java @End 注解的静态校验能力,但可以通过拆分类型完全实现漏写 run() 就触发编译报错的效果:

// 仅包含链式调用方法的类型,不暴露run方法
interface UserActionChain {
  attemptsTo(tasks: (() => Promise<void>)[]): UserActionChain
  expects(expectations: (() => Promise<void>)[]): UserActionChain
}

// 可执行的子类型,新增run方法
interface RunnableUser extends UserActionChain {
  run(): Promise<void>
}

class User implements RunnableUser {
  public name: string;
  public works: (() => Promise<void>)[];

  constructor(name: string) {
    this.name = name;
    this.works = [];
  }

  public attemptsTo(tasks: (() => Promise<void>)[]): UserActionChain {
    this.works.push(...tasks);
    return this;
  }

  public expects(expectations: (() => Promise<void>)[]): UserActionChain {
    this.works.push(...expectations);
    return this;
  }

  async run(): Promise<void> {
    for (const work of this.works) {
      await work();
    }
  }
}

// 工厂函数返回链式类型,屏蔽初始实例的run方法
function createUser(name: string): UserActionChain {
  return new User(name);
}

使用效果:

  • 漏写run()直接编译报错:await createUser("Admin").attemptsTo([...]) 会提示类型不存在then方法,无法直接await
  • 只有末尾添加run()才会通过类型校验:await createUser("Admin").attemptsTo([...]).run() 正常执行
方案2:完全省略run()调用,自动执行任务

如果不想额外写run(),可以让类实现PromiseLike接口,await实例时自动触发所有任务执行:

class User implements PromiseLike<void> {
  public name: string;
  public works: (() => Promise<void>)[];

  constructor(name: string) {
    this.name = name;
    this.works = [];
  }

  public attemptsTo(tasks: (() => Promise<void>)[]): this {
    this.works.push(...tasks);
    return this;
  }

  public expects(expectations: (() => Promise<void>)[]): this {
    this.works.push(...expectations);
    return this;
  }

  // 实现PromiseLike标准接口,await时自动执行
  then<TResult1 = void, TResult2 = never>(
    onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null | undefined,
    onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
  ): PromiseLike<TResult1 | TResult2> {
    const runAllTasks = async () => {
      for (const work of this.works) {
        await work();
      }
    };
    return runAllTasks().then(onfulfilled, onrejected);
  }
}

使用方式:

const admin = new User("Admin");
await admin
  .attemptsTo([EnterCredentials, Login])
  .expects([LoginSuccessfully])
  .attemptsTo([NavigateToUsersPage])
  .expects([SeeUsersList, AddNewUser]);
// 无需调用.run(),await时自动执行所有任务

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 17:24:10