Typescript: Wie man eine Klasse definiert, die aufrufbare Instanzen erzeugt
Ich konvertiere derzeit eine JS-Klasse nach TypeScript. Die Klasse erweitert das NPM-Modul node-callable-instance (welches sie intern zu einer Unterklasse von Function macht). Instanzen der Klasse können wie Funktionen aufgerufen werden. Kurzes Beispiel:
import * as CallableInstance from "callable-instance";
class MyClass extends CallableInstance {
constructor() { super('method'); }
method(msg) { console.log(msg); }
}
const inst = new MyClass();
inst('test'); // call will be forwarded to "method()"
Es ist eine Anforderung dieses speziellen Projekts, dass diese Instanzen aufrufbar sind, andere Build-Zeit-Werkzeuge hängen davon ab.
Gibt es eine Möglichkeit, das in TypeScript auszudrücken? Der obige Code ergibt
Fehler TS2349: Ein Ausdruck, dessen Typ keine Aufrufsignatur besitzt, kann nicht aufgerufen werden. Der Typ 'MyClass' hat keine kompatiblen Aufrufsignaturen.
Mein erster Versuch, dies durch die Verwendung eines aufrufbaren Interfaces zu umgehen, schlug fehl, da die Klasse die Aufruf-Signatur nicht implementiert...
import * as CallableInstance from "callable-instance";
interface MyClassCallable {
(msg: string): void;
}
class MyClass extends CallableInstance implements MyClassCallable {
constructor() { super('method'); }
method(msg: string): void { console.log(msg); }
}
const inst = new MyClass();
inst('test'); // call will be forwarded to "method()"
Antwort #1
Die einfachste Lösung besteht darin, Interface-Klassen-Merging zu verwenden und ein Interface mit demselben Namen zu deklarieren, das die aufrufbare Signatur hat. Der resultierende Typ wird Mitglieder haben, die sowohl durch das Interface als auch durch die Klasse definiert sind:
import * as CallableInstance from "callable-instance";
class MyClass extends CallableInstance {
constructor() { super('method'); }
method(msg: string): void { console.log(msg); }
}
interface MyClass {
(name: string): void
}
const inst = new MyClass();
inst('test'); // call will be forwarded to "method()"
