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

如何使用TypeScript方法装饰器强制方法必须包含executionTime参数

实现方案

核心逻辑说明

通过方法装饰器在类加载阶段自动校验被装饰方法的参数列表,如果不存在executionTime参数直接抛出错误,同时可以额外增加TS类型校验实现编译期提前报错。

完整代码实现

class AllEvents {
  @performanceDecorator()
  public static firstEvent(param1: string, param2: string, executionTime: number): void {
    //some tasks...
  }

  // 该方法会触发错误提示
  @performanceDecorator()
  public static secondEvent(param1: string, param2: string): void {
    //some tasks...
  }

  @performanceDecorator()
  public static thirdEvent(param1: string, param2: string, executionTime: number): void {
    //some tasks...
  }
}

/**
 * 性能采集装饰器工厂,可传入自定义配置参数
 */
function performanceDecorator() {
  // 装饰器执行逻辑
  return function (target: any, methodName: string | symbol, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    // 提取方法的参数名列表
    const paramNames = getFunctionParamNames(originalMethod);
    
    // 执行参数校验
    if (!paramNames.includes('executionTime')) {
      throw new Error(`方法 ${String(methodName)} 缺失必填参数executionTime,禁止使用@performanceDecorator装饰器`);
    }

    // 校验通过后原样返回方法描述符,后续扩展性能采集逻辑也可以在这里处理
    return descriptor;
  }
}

/**
 * 工具方法:提取函数的参数名列表,自动过滤注释、默认值等干扰内容
 */
function getFunctionParamNames(func: Function): string[] {
  const fnStr = func.toString()
    // 移除多行注释
    .replace(/\/\*[\s\S]*?\*\//g, '')
    // 移除单行注释
    .replace(/\/\/.*$/gm, '')
    .trim();
  // 匹配普通函数、箭头函数的参数段
  const paramMatch = fnStr.match(/^(?:function\s*[^(]*\()|(?:^\s*\(?)\s*([^)]*)\)?/m);
  
  if (paramMatch?.[1]) {
    return paramMatch[1].split(',')
      .map(param => param.trim().split('=')[0].trim())
      .filter(Boolean);
  }
  return [];
}

扩展:编译期提前校验

如果希望在编码阶段就得到参数错误提示,不需要等到运行时才报错,可以补充TS类型校验逻辑,修改装饰器的类型定义即可:

// 定义类型约束:要求方法最后一个参数必须是number类型的executionTime
type WithExecutionTime<T extends (...args: any[]) => any> = 
  T extends (...args: infer P) => infer R 
    ? P extends [...rest: any[], executionTime: number] ? T : never 
    : never;

function performanceDecorator() {
  return function <T extends (...args: any[]) => any>(target: any, methodName: string | symbol, descriptor: TypedPropertyDescriptor<T>) {
    // 原有的运行时校验逻辑保留
    const originalMethod = descriptor.value!;
    const paramNames = getFunctionParamNames(originalMethod);
    if (!paramNames.includes('executionTime')) {
      throw new Error(`方法 ${String(methodName)} 缺失必填参数executionTime,禁止使用@performanceDecorator装饰器`);
    }
    // 返回带类型约束的描述符,触发TS编译校验
    return descriptor as TypedPropertyDescriptor<WithExecutionTime<T>>;
  }
}

修改后没有加executionTime参数的方法在编码阶段就会被TS标红提示类型不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:12:01