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

6pp0gazn  于 2023-05-08  发布在  TypeScript
关注(0)|答案(6)|浏览(355)

我的测试代码如下:

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

jq6vz3qz

jq6vz3qz1#

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

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

wbgh16ku2#

使用--target ES5 --emitDecoratorMetadata --experimentalDecorators
或使用以下配置:

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

e37o9pze3#

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

***该消息充其量是误导性的;这个问题与解析签名的能力无关,或者说与缺乏解析签名的能力无关。**相反,它表明了装饰器上的输入问题。例如,以下代码信号TS 1241在@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");
    }
}

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

*decorator的调用约定,也就是decorator的类型**取决于目标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())完全满意。
因此,最简单的解决方法是**假装第三个参数是可选的,**即

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,这种“欺骗”尤其重要,在这种情况下,您绝对不想在tsconfig.json中更改"target"设置。

xam8gpfp

xam8gpfp4#

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

ffvjumwh5#

如果使用的是
()=> {}
函数表示法,切换到常规表示法
function(){

drnojrws

drnojrws6#

这个错误来自typescript编译

修复此错误。你必须将tsconfig.json添加到你的项目目录中。如果你愿意,你可以按照这个config代码。

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

相关问题