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

时间:2016-06-08 05:57:39

标签: typescript decorator

我的测试代码如下:

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

5 个答案:

答案 0 :(得分:14)

似乎TypeScript期望装饰器函数的返回类型为“any”或“void”。因此,在下面的示例中,如果我们将: any添加到最后,它最终会正常工作。

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

答案 1 :(得分:6)

使用--target ES5 --emitDecoratorMetadata --experimentalDecorators

或使用以下配置:

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

答案 2 :(得分:2)

随着时间的流逝,此隐秘错误消息似乎有多种根本原因。截至2019年底,我可以收集到以下信息:

  • 该消息充其量是一种误导;该问题与解析签名的能力或签名的缺乏无关。相反,它表明装饰者存在打字问题。例如,以下代码signals TS1241 at @f(), but not at @g()
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(): evaluated main-2.js line 1134 > eval:9:13
    g(): evaluated main-2.js line 1134 > eval:15:13
    g(): called with 2 arguments main-2.js line 1134 > eval:17:17
    f(): called with 2 arguments
    (?在trying out the code on typescriptlang.org/play时,首先在浏览器的开发人员工具中打开JavaScript控制台;然后单击“运行”。)
    另一方面,running the very same code under "target": "ES5"产生{{2} },因此,TypeScript对@f()(以及@g())也很满意。

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

f(): evaluated main-2.js line 1134 > eval:9:13
g(): evaluated main-2.js line 1134 > eval:15:13
g(): called with 3 arguments main-2.js line 1134 > eval:17:17
f(): called with 3 arguments

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

如果使用angular-meteor,此“欺骗”尤为重要,在这种情况下,您绝对不想想要弄乱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"设置

答案 3 :(得分:1)

如果您使用的是

,也会出现此错误

()=> {}

功能符号,切换为常规符号

function(){}

答案 4 :(得分:0)

将此命令添加到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;
  };