typescript TS1241:作为表达式调用时无法解析方法装饰器的签名

问题描述 投票:0回答:9

我的测试代码如下:

function test(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
    return descriptor;
}

class Test {
    @test
    hello() {
    }
}

但是编译器给我错误

Error:(33, 5) TS1241: Unable to resolve signature of method decorator when called as an expression.
 Supplied parameters do not match any signature of call target.

我已经指定了:

--experimentalDecorators --emitDecoratorMetadata
typescript decorator
9个回答
59
投票

使用

--target ES5 --emitDecoratorMetadata --experimentalDecorators

或使用以下配置:

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "ES5"
  }
}

44
投票

TypeScript 似乎期望装饰器函数的返回类型为“any”或“void”。因此,在下面的示例中,如果我们将

: any
添加到末尾,它就会正常工作。

function test(target: Object, 
              propertyKey: string, 
              descriptor: TypedPropertyDescriptor<any>): any {
    return descriptor;
}

33
投票

随着时间的推移,这个神秘的错误消息似乎有多个根本原因。截至 2019 年底,我可以收集到以下信息:

function f() {
    console.log("f(): evaluated");
    return function (targetClass: any, propertyKey: string, descriptor: TypedPropertyDescriptor<() => void>) {
        console.log("f(): called with " + arguments.length + " arguments");
    }
}

function g() {
    console.log("g(): evaluated");
    return function (target: any, propertyKey: string) {
        console.log("g(): called with " + arguments.length + " arguments");
    }
}

class C {
    @f()      // TypeScript signals TS1241 here
    @g()      // but not there
    method() { }
}
  • 装饰器的调用约定,以及它们的类型,取决于目标 JavaScript 方言。例如,使用
    {"compilerOptions": { "target": "ES3" } }
    运行上述代码会产生
    f():计算出 main-2.js 第 1134 行 >评估:9:13
    g():评估 main-2.js 第 1134 行 > eval:15:13
    g():使用 2 个参数调用 main-2.js 第 1134 行 > eval:17:17
    f():使用 2 个参数调用
    (💡 当
    typescriptlang.org/play
    上尝试代码时,首先在浏览器的开发人员工具中打开 JavaScript 控制台;然后单击“运行”)。
    另一方面,运行相同的代码
    "target": "ES5"
    下的代码导致
    f(): 评估 main-2.js 第 1134 行 > eval:9:13
    g():评估 main-2.js 第 1134 行 > eval:15:13
    g():使用 3 个参数调用 main-2.js 第 1134 行 > eval:17:17
    f():使用 3 个参数调用
    
    因此,在这种情况下,TypeScript 对
    @f()
    (以及
    @g()
    )非常满意。

因此,最简单的解决方法是假装第三个参数是可选的,

function f() {
    console.log("f(): evaluated");
    return function (targetClass: any, propertyKey: string, descriptor?: TypedPropertyDescriptor<() => void>) {
        console.log("f(): called with " + arguments.length + " arguments");
    }
}

class C {
    @f()
    method() { }
}

"target": "ES3"
"target": "ES5"
下都能成功进行类型检查。

如果使用angular-meteor,这个“作弊”尤其重要,在这种情况下,你绝对不想想要弄乱

"target"
中的
tsconfig.json
设置。


4
投票

在 tsconfig 中添加此命令以使用装饰器。

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "ES5"
  }
}

装饰器函数应该是这样的。

function(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
    descriptor.value = async function(...args: any) {
      try {
        const result = await originalMethod.apply(this, args);
        return result;
      } catch (error) {
         console.log(error)
      }
    };

    return descriptor;
  };

2
投票

如果您使用

,您也可能会收到此错误

() => {}

函数表示法,切换到常规表示法

函数(){}


2
投票

这个错误来自打字稿编译

修复此错误。您必须将

tsconfig.json
添加到您的项目目录中。然后,如果您愿意,可以按照此
config
代码进行操作。

{
  "compilerOptions": {
     "lib": [
        "es5",
        "es6"
     ],
     "target": "es6",
     "module": "commonjs",
     "moduleResolution": "node",
     "outDir": "./build",
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "sourceMap": true,
     "esModuleInterop": true
  }
}

2
投票

我在 vsCode 中报告了此错误,但在编译时/运行时一切正常。 error shown in vsCode

我通过检查

js/ts.implicitProjectConfig.experimentalDecorators
设置修复了它。


0
投票

最近 tsyringe 也出现同样的问题。我在装饰器之前添加@ts-ignore...

//@ts-ignore
public constructor(@inject(MongoClient) private client: MongoClient) {

0
投票

我使用

NestJS + Deno + GraphQL + npm packages
找到了针对此问题以及项目中相关错误的单行解决方案。其他解决方案对我不起作用。因此,在这里分享它,因为它可能会帮助别人节省一些时间。它可能与使用其他运行时(如 Bun、Node)的项目相关。

您可以在这里找到详细答案>> https://stackoverflow.com/a/79107940/13607767

© www.soinside.com 2019 - 2024. All rights reserved.