簡體   English   中英

打字稿 TS1241:作為表達式調用時無法解析方法裝飾器的簽名

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

我的測試代碼如下:

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 期望裝飾器函數的返回類型為“any”或“void”。 所以在下面的例子中,如果我們在末尾添加: any ,它最終會起作用。

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

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

或使用以下配置:

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

隨着時間的推移,這個神秘的錯誤消息似乎有多個根本原因。 截至 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" } }運行上面的代碼會導致
    \n f(): 評估 main-2.js 行 1134 > eval:9:13\n g(): 評估 main-2.js 行 1134 > eval:15:13\n g(): 使用 2 個參數調用 main-2.js line 1134 > eval:17:17\n f():使用 2 個參數調用
    (💡當上嘗試代碼typescriptlang.org/play ,首先打開瀏覽器的開發者工具JavaScript控制台,然后單擊運行)。
    另一方面, "target": "ES5"下運行相同的代碼會導致
    \n f(): 評估 main-2.js 行 1134 > eval:9:13\n g(): 評估 main-2.js 行 1134 > eval:15:13\n g(): 使用 3 個參數調用 main-2.js line 1134 > eval:17:17\n f():使用 3 個參數調用\n
    因此,在這種情況下,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"下成功進行類型檢查。

如果使用這種“欺騙”是特別重要的角流星,在這種情況下,你最肯定不想"target"中設置tsconfig.json

如果您正在使用,您也可能會收到此錯誤

() => {}

函數符號,切換到常規符號

函數(){}

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM