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

TypeScript方法装饰器报错:无法解析签名及类型不兼容问题

解决Playwright测试中TypeScript装饰器的类型错误

错误原因分析

你遇到的两个TypeScript错误本质是装饰器的类型定义和实际用法不匹配:

  1. TS1241错误:实例方法装饰器的第一个参数并非方法本身,而是类的原型对象(比如Component.prototype),但你把target定义成了函数类型GenericFunction,导致类型不兼容。
  2. TS1270错误:原方法是同步返回void,但装饰后返回Promise<unknown>(test.step的返回值),同时替换函数的参数是unknown[],和原方法的(name: string)参数类型不匹配,类型系统无法通过校验。

修正后的代码

使用泛型实现类型安全的装饰器,保留原方法的上下文、参数和返回类型:

import { test, expect, Page } from '@playwright/test';

// 泛型装饰器,适配任意类的实例方法
function step<This, Args extends unknown[], Return>(
  target: (this: This, ...args: Args) => Return,
  context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
) {
  return function replacementMethod(this: This, ...args: Args) {
    const className = this.constructor.name;
    if (typeof context.name !== 'string') {
      throw new Error('Method name is not a string');
    }

    const methodName = context.name;
    const argsString = args.map(arg => JSON.stringify(arg)).join(', ');

    // 兼容同步/异步方法,统一返回Promise(符合test.step的行为)
    return test.step(`${className}.${methodName}(${argsString})`, async () => {
      const result = target.call(this, ...args);
      return 'then' in (result as Promise<Return>) ? await result : result;
    });
  };
}

class Component {
  constructor(private page: Page) {}

  @step
  checkComponent(name: string) {
    expect(name).toEqual('button');
  }

  // 测试异步方法适配
  @step
  async clickButton() {
    await this.page.click('button');
  }
}

// tsconfig.json 核心配置
{
  "target": "es2018",
  "experimentalDecorators": true,
  "emitDecoratorMetadata": true,
  "lib": ["es2018"]
}

关键改动说明

  • 泛型参数约束:通过<This, Args, Return>分别捕获原方法的上下文、参数列表和返回类型,确保装饰器能适配任意类的实例方法,同时保留类型安全。
  • 修正target类型:让target的类型和原方法、装饰器上下文的类型完全对齐,解决TS1241错误。
  • 同步/异步兼容:自动处理原方法的同步/异步返回值,确保装饰后返回的Promise类型和原方法的返回值类型匹配,解决TS1270错误。
  • 参数类型严格匹配:替换函数的参数列表严格继承原方法的类型,避免unknown[]导致的类型丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:50:12