typescript - Warum `Error:(3, 1) TS1238: Kann die Signatur des Klassendekorators nicht auflösen, wenn er als Ausdruck aufgerufen wird` Fehler
Ich habe den folgenden Dekorator:
export function MyClassDecorator(): PropertyDecorator {
return function (target: Function) {
Object.seal(target);
Object.seal(target.prototype);
}
}
Und ich benutze es so:
import {ClassDecorator} from "./class-decorator";
@MyClassDecorator()
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
Allerdings meldet tsc einen Fehler:
Error:(3, 1) TS1238:Unable to resolve signature of class decorator when called as an expression.
Supplied parameters do not match any signature of call target.
Die Lösung wäre, PropertyDecorator in ClassDecorator zu ändern:
export function MyClassDecorator(): ClassDecorator {
Die Frage ist jedoch, warum der Fehler bei PropertyDecorator auftritt?
Hier ist, wie Klassen- und Eigenschafts-Dekoratoren in lib.d.ts deklariert werden:
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
Antwort #1
Eigenschafts-Dekoratoren werden innerhalb der Klassendefinition verwendet und nicht oberhalb der Klasse. Ihr Eigenschafts-Dekorator befindet sich dort, wo ein Klassendekorator platziert werden sollte.
Die Warnung im Zusammenhang mit Signaturen könnte erscheinen, weil der target-Parameter in ClassDecorator tatsächlich eine Konstruktionsfunktion sein muss, während es im PropertyDecorator ein allgemeineres Objekt ist. Vielleicht kann TS den Unterschied darauf basierend erkennen, wo Sie den Dekorator platzieren.
Zum Beispiel, wenn Sie einfach den Rückgabewert für MyClassDecorator entfernen, erkennt TS automatisch den Typ für diese Funktion und alles funktioniert:
function MyClassDecorator() {
return function (target: Function) {
Object.seal(target);
Object.seal(target.prototype);
};
}
@MyClassDecorator()
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
