web-dev-qa-db-fra.com

TS1241: impossible de résoudre la signature du décorateur de méthode lorsqu'il est appelé en tant qu'expression

Mon code de test est le suivant:

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

class Test {
    @test
    hello() {
    }
}

mais le compilateur me donne une erreur

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.

J'ai déjà spécifié: --experimentalDecorators --emitDecoratorMetadata

23
Jeff

Il semble que TypeScript s'attende à ce que le type de retour de la fonction de décorateur soit 'any' ou 'void'. Donc, dans l'exemple ci-dessous, si nous ajoutons : any à la fin, ça finit par fonctionner.

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

Utilisation --target ES5 --emitDecoratorMetadata --experimentalDecorators

ou utilisez la configuration suivante:

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

Ce message d'erreur cryptique semble avoir eu plusieurs causes profondes au fil du temps. Fin 2019, voici ce que j'ai pu rassembler:

  • Le message est au mieux trompeur; le problème n'a rien à voir avec la capacité à résoudre les signatures, ou leur absence. Au contraire, cela signale un problème de frappe sur les décorateurs. Par exemple, le code suivant signale TS1241 à @f(), mais pas à @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() { }
}
  • La convention d'appel sur les décorateurs , et donc leur type, dépend du dialecte JavaScript ciblé. Par exemple, l'exécution du code ci-dessus avec {"compilerOptions": { "target": "ES3" } } Donne
     f (): évalué main-2.js ligne 1134> eval: 9: 13 
     g (): évalué main-2.js ligne 1134> eval: 15: 13 
     g (): appelé avec 2 arguments main-2.js ligne 1134> eval: 17: 17 
     f (): appelé avec 2 arguments
    (???? Quand essayer le code sur typescriptlang.org/play , ouvrez d'abord la console JavaScript dans les outils de développement de votre navigateur, puis cliquez sur Exécuter).
    D'un autre côté, exécuter le même code sous "target": "ES5" donne
     f (): évalué main-2.js ligne 1134> eval: 9: 13 
     g (): évalué main-2.js ligne 1134> eval: 15: 13 
     g (): appelé avec 3 arguments main-2.js ligne 1134> eval: 17: 17 
     f (): appelé avec 3 arguments 
    
    et en conséquence, TypeScript est entièrement satisfait de @f() (et également @g()) dans ce cas.

La solution de contournement la plus simple est donc de prétendre que le troisième paramètre est facultatif, 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() { }
}

qui vérifie le type avec succès sous "target": "ES3" et "target": "ES5" .

Cette "triche" est particulièrement importante si vous utilisez météore angulaire , auquel cas vous devez absolument ne le faites pas vous voulez jouer avec le paramètre "target" Dans tsconfig.json.

5
DomQ

Ajoutez cette commande dans tsconfig pour utiliser le décorateur.

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

La fonction de décorateur devrait aimer ceci.

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

Vous pouvez également obtenir cette erreur si vous utilisez

() => {}

notation de fonction, passer à la notation régulière

fonction() {}

0
Jason G