Historique de la question : En JavaScript, les fonctions de rappel sont omniprésentes, mais leurs signatures sont souvent peu claires. En TypeScript, il est important d'indiquer explicitement les types des paramètres et la valeur de retour, sinon il est facile de créer des failles dans la sécurité des types.
Problème : Une typisation incorrecte ou laxiste des callbacks conduit à des types d'arguments et de résultats indéfinis, complique le travail avec le contexte (this), casse la vérification automatique des erreurs par le compilateur et rend le refactoring difficile.
Solution : Il est nécessaire de définir clairement le type de la fonction de rappel, d'indiquer les types des paramètres passés, de gérer correctement les arguments optionnels et la valeur de retour, et, si nécessaire, de spécifier explicitement le type du contexte.
Exemple de code :
type Callback = (error: Error | null, result?: string) => void; function doAsyncWork(data: string, cb: Callback): void { setTimeout(() => { if (data === '') cb(new Error('Chaîne vide')); else cb(null, data.toUpperCase()); }, 100); }
Caractéristiques clés :
Que se passe-t-il si je ne spécifie pas le type de retour du callback ?
TypeScript acceptera n'importe quel type de retour (par exemple, undefined, void, Promise), ce qui peut entraîner des surprises dans des chaînes asynchrones ou lors du retour de valeurs "par défaut".
type BadCallback = (data: string) => any; // n'importe quel résultat, absence de contrôle
Est-il acceptable d'écrire un callback comme Function ou (...args: any[]) => any ?
Non. Cela supprime toute protection de type, perdant ainsi les informations sur le nombre de paramètres, leurs types et le type de retour. Cette approche coûte plus cher que de renoncer complètement à TypeScript.
Comment typer une fonction avec le contexte this ?
Utilisez le premier paramètre this dans la signature de la fonction ou le cast via bind. Par exemple :
interface ClickCallback { (this: HTMLElement, event: MouseEvent): void; } const handler: ClickCallback = function (event) { this.textContent = 'ok'; };
Dans le projet, le callback a été déclaré comme (...args: any[]) => any. Lorsque la logique métier a été mise à jour, la signature a changé, le callback a cessé de transmettre les arguments nécessaires, et les bugs n'ont été découverts qu'en production.
Avantages :
Inconvénients :
Des types stricts ont été introduits : les interfaces des callbacks ont été décrites, le type de this et le type de retour ont été clairement spécifiés. Le compilateur a commencé à détecter les erreurs avant le déploiement, et le refactoring ainsi que le support pour le dépannage ont été simplifiés.
Avantages :
Inconvénients :