web-dev-qa-db-ja.com

typescript TS1241:式として呼び出されたときにメソッドデコレータの署名を解決できません

私のテストコードは次のようなものです:

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

23
Jeff

TypeScriptは、デコレータ関数の戻り値の型が 'any'または 'void'であると想定しているようです。したがって、以下の例では、最後に: anyを追加すると、機能します。

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

使用する --target ES5 --emitDecoratorMetadata --experimentalDecorators

または、次の構成を使用します。

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "ES5"
  }
}
15
Tuong Le

この不可解なエラーメッセージには、時間の経過とともに複数の根本的な原因があったようです。 2019年末現在、私が集めることができるものは次のとおりです。

  • メッセージはせいぜい誤解を招くだけです。この問題は、署名を解決する機能やその欠如とは関係ありません。むしろ、デコレータでの入力の問題を示します。たとえば、次のコード @f()でTS1241に通知しますが、@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():評価されたmain-2.js行1134> eval:9:13 
     g():評価されたmain-2.js行1134> eval:15:13 
     g():2つの引数で呼び出されますmain-2.js line 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 line 1134> eval:17:17 
     f():3つの引数で呼び出されます
    
    したがって、TypeScriptはその場合、@f()(および@g())にも完全に満足しています。

したがって、最も簡単な回避策は、3番目のパラメータがオプションであると偽ってです。

_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_の設定。

5
DomQ

このコマンドを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;
  };

使用している場合にもこのエラーが発生する可能性があります

()=> {}

関数表記、通常表記に切り替え

関数() {}

0
Jason G