En TypeScript, les fonctions asynchrones (async/await) retournent toujours un Promise. Le type de la valeur de retour est spécifié ainsi : Promise<Type>. Lors de la description de la fonction, il est important de typiser explicitement le résultat pour que TypeScript puisse travailler correctement avec les types à l'intérieur de la promesse. Des erreurs de typage peuvent survenir si les valeurs intermédiaires ne correspondent pas à celles déclarées.
Fonction asynchrone :
async function fetchUser(id: number): Promise<User> { const response = await fetch(`/api/user/${id}`); const data: User = await response.json(); return data; }
Si la fonction doit retourner une erreur ou un rejet, le type de la promesse ne doit pas décrire l'erreur directement (Promise<Error>), car le rejet de la promesse n'est pas typisé et est capturé via catch.
La typisation des chaînes de promesses est importante :
function getNumber(): Promise<number> { return Promise.resolve(42); } getNumber().then(val => val.toFixed(2)); // TypeScript sait que val est un nombre
Question : Une fonction asynchrone peut-elle retourner quelque chose d'autre qu'une promesse ?
Réponse : Non. Une fonction asynchrone retourne toujours un objet Promise. Si une valeur non-promesse est explicitement retournée, TypeScript enveloppera automatiquement la valeur de retour dans une promesse.
async function test() { return 1; } const result = test(); type ResultType = typeof result; // Promise<number>
Histoire
Un développeur a écrit une fonction sans typage explicite de la valeur de retour, supposant qu'elle retourne un objet d'un certain type. Lors de la modification de la logique, la fonction a commencé à retourner un autre type, et cela n'a pas été remarqué immédiatement, car TypeScript, sur la base de l'inférence de type, n'a pas signalé d'erreur. En fin de compte, les erreurs se sont manifestées uniquement à l'exécution, lorsque le consommateur de la fonction a tenté d'appeler une propriété inexistante.
Histoire
Dans un projet, les chaînes de promesses n'ont pas été typisées. Tenter d'accéder à une méthode inexistante sur le résultat entraînait des erreurs. Ainsi, le résultat then(response => response.data) était considéré comme any, et l'erreur d'accès aux champs ou méthodes ne se manifestait qu'à l'exécution. L'erreur est passée en production et n'a été détectée qu'avec l'aide des utilisateurs.
Histoire
Une fonction asynchrone a été déclarée avec le type Promise<Error>, pensant que cela permettrait de capturer les erreurs, mais en réalité, les erreurs n'ont pas été propagées via throw et la promesse a été rejetée avec un autre type de valeur. Cela a conduit à un mélange implicite d'erreurs et de valeurs valides, entraînant des bugs dans la logique de traitement des résultats des promesses.