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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37694322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:33:48  来源:igfitidea点击:

typescript TS1241: Unable to resolve signature of method decorator when called as an expression

typescriptdecorator

提问by Jeff

My test code is like the following:

我的测试代码如下:

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

class Test {
    @test
    hello() {
    }
}

but the compiler give me error

但是编译器给了我错误

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.

I have already specified: --experimentalDecorators --emitDecoratorMetadata

我已经指定:--experimentalDecorators --emitDecoratorMetadata

回答by Doguhan Uluca

It seems that TypeScript expects the return type of the decorator function to be 'any' or 'void'. So in the example below, if we add : anyto the end, it ends up working.

似乎 TypeScript 期望装饰器函数的返回类型为“any”或“void”。所以在下面的例子中,如果我们添加: any到最后,它最终会起作用。

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

回答by Tuong Le

Use --target ES5 --emitDecoratorMetadata --experimentalDecorators

利用 --target ES5 --emitDecoratorMetadata --experimentalDecorators

or use the following config:

或使用以下配置:

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

回答by DomQ

This cryptic error message seems to have had multiple root causes over time. As of end of 2019, here is what I could gather:

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

  • The message is misleading at best; the problem has nothing to do with ability to resolve signatures, or lack thereof.Rather, it signals a typing problem on the decorators. For instance, the following code 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() { }
}
  • The calling convention on decorators, and therefore their type, depends on the targeted JavaScript dialect.For instance, running the above code with {"compilerOptions": { "target": "ES3" } }results in
    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
    ( When trying out the code on typescriptlang.org/play, first open the JavaScript console in your browser's Developer Tools; then click Run).
    On the other hand, running the very same code under "target": "ES5"results in
    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
    
    and accordingly, TypeScript is fully happy with @f()(and also @g()) in that case.
  • 装饰器的调用约定及其类型取决于目标 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
    (在 上试用代码时typescriptlang.org/play,首先在浏览器的开发人员工具中打开 JavaScript 控制台;然后单击运行)。
    另一方面,"target": "ES5"结果下运行相同的代码
    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
    
    因此,在这种情况下,TypeScript 对@f()(以及@g())完全满意。

The simplest workaround is therefore to pretend that the third parameter is optional,i.e.

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

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() { }
}

which type-checks successfully under both "target": "ES3"and "target": "ES5".

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

This “cheat” is especially important if using angular-meteor, in which case you most definitely do notwant to mess with the "target"setting in tsconfig.json.

如果使用这种“欺骗”是特别重要的角流星,在这种情况下,你最肯定希望与混乱"target"的环境tsconfig.json

回答by Akila K Gunawardhana

Add this command in tsconfig for use decorator.

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

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

Decorator function should like this.

装饰器功能应该是这样的。

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;
  };

回答by Jason G

You can also get this error if you are using

如果您正在使用,您也可能会收到此错误

() => {}

() => {}

function notation, switch to regular notation

函数符号,切换到常规符号

function() {}

功能() {}