In TypeScript geven asynchrone functies (async/await) altijd een Promise terug. Het type van de retourwaarde wordt als volgt aangegeven: Promise<Type>. Bij het beschrijven van de functie is het belangrijk om het resultaat expliciet te typeren, zodat TypeScript correct met de types binnen de bel werkt. Typfouten kunnen ontstaan als tussenliggende waarden niet overeenkomen met wat er is gedeclareerd.
Asynchrone functie:
async function fetchUser(id: number): Promise<User> { const response = await fetch(`/api/user/${id}`); const data: User = await response.json(); return data; }
Als de functie een fout of afwijzing moet retourneren, moet het type van de bel de fout niet rechtstreeks beschrijven (Promise<Error>), omdat de afwijzing van de bel niet getypeerd wordt, maar wordt gevangen via catch.
Typisering van belsamenkoppelingen is belangrijk:
function getNumber(): Promise<number> { return Promise.resolve(42); } getNumber().then(val => val.toFixed(2)); // TypeScript weet dat val een nummer is
Vraag: Kan een asynchrone functie iets teruggeven behalve een bel?
Antwoord: Nee. Een asynchrone functie geeft altijd een Promise object terug. Als je expliciet iets anders dan een bel retourneert, wikkelt TypeScript de retourwaarde automatisch in een bel.
async function test() { return 1; } const result = test(); type ResultType = typeof result; // Promise<number>
Verhaal
Een ontwikkelaar heeft een functie geschreven zonder expliciete typisering van de retourwaarde, in de veronderstelling dat deze een object van een bepaald type retourneert. Bij het wijzigen van de logica begon de functie een ander type terug te geven, en dit werd niet meteen opgemerkt, omdat TypeScript, op basis van het typeafgeleide resultaat, geen fout gaf. Uiteindelijk manifesteerden de fouten zich pas tijdens runtime, toen de consument van de functie probeerde een niet-bestaande eigenschap aan te roepen.
Verhaal
In een project waren de belsamenkoppelingen niet getypeerd. De poging om een niet-bestaande methode op het resultaat aan te roepen leidde tot fouten. Zo werd het resultaat then(response => response.data) als any beschouwd, en de fout met het vangen van velden of methoden openbaarde zich pas tijdens runtime. De fout ging naar productie en werd alleen ontdekt door gebruikers.
Verhaal
De asynchrone functie werd gedeclareerd met het type Promise<Error>, in de veronderstelling dat dit zou helpen bij het vangen van fouten, maar in werkelijkheid werden de fouten niet doorgegeven via throw en werd de bel afgewezen met een ander type waarde. Dit leidde tot een impliciete mengeling van fouten en geldige waarden, en het ontstaan van bugs in de logica voor het verwerken van de resultaten van bels.