J'ai une classe avec des types de membres mixtes, des champs et des méthodes (par exemple MyClass
ci-dessous). J'essaie d'avoir une commande créée qui appelle une fonction et est capable de l'exécuter tout en conservant le contexte this
.
Le code ci-dessous fonctionne si j'utilise une classe qui n'a pas de champs en elle, seulement des membres appelables (par exemple, si je commente public field: number = 1;
) Cela fonctionne bien, bon sens du type, erreurs si la méthode de la classe n'existe pas, erreurs si les paramètres sont mauvais. mais il semble ne pas apprécier lorsque je passe une classe qui a des membres non appelables. Peut-être que vous avez une solution pour cela?
class MyClass{
constructor() {}
public field: number = 1;
public printMessage(): void{
console.log("message")
}
public printNumber(i: number): number{
return i;
}
}
type TypeOfClassMethod = T[M] extends Function ? T[M] : never;
interface ICommand{
execute(): any;
}
class Command implements ICommand{
api: MyClass;
constructor(
api: MyClass,
private func: TypeOfClassMethod,
private args: Parameters> //
) {
this.api = api;
}
execute(): ReturnType>{
// error[1] type ‘TypeOfClassMethod’ does not satisfy the constraint ‘(...args: any) => any’.
// Type ‘Function & MyClass[F]’ is not assignable to type ‘(...args: any) => any’.
return this.func.call(this.api, ...this.args)
}
}
let instance = new MyClass();
const command = new Command<"printNumber">(instance, instance.printNumber, [5] );
const wrongCOmmand = new Command<"field">(instance, instance.field, [] );
MODIFIER : Mon principal problème avec le code que j'avais est qu'il génère des erreurs si j'ai des membres non-fonction dans une classe, je veux que cela fonctionne pour d'autres classes qui ont des membres non exécutables mais me donnent une erreur si je veux créer une commande avec un membre qui n'est pas exécutable.
En gros, je veux appeler cela dans une fonction de wrapper callWithRetry
à laquelle est passée une commande et est exécutée jusqu'à ce qu'elle réussisse ou qu'un certain critère d'arrêt soit atteint.
Jetez un œil ici, par exemple (terrain de jeu TS)
Ou celui-ci qui est basé sur la deuxième option de votre première réponse
Les deux manquent de type de retour lorsque j'essaie de l'appeler à l'intérieur d'une fonction.
function executeCommand(command: Command) {
// je veux l'utiliser de manière similaire à cela, dans un mécanisme de réessai, mais dans ce cas je perds le returnType
return command.execute()
}
const result = executeCommand(command); // le résultat aura un type de retour de any
MISE À JOUR : Je l'ai fait fonctionner comme je le voulais, merci beaucoup pour l'aide! voici la solution dans TS playground