ReturnType<T> en Parameters<T> zijn utility types in TypeScript die het mogelijk maken om automatisch het type van de teruggegeven waarde van een functie af te leiden (ReturnType) of een array van types van haar parameters (Parameters).
Dit is bijzonder handig voor het waarborgen van typeconsistentie tussen verschillende delen van de applicatie en voor het implementeren van generic wrappers.
Voorbeeld van gebruik:
function fn(a: number, b: string): boolean { return b.length > a; } type FnReturn = ReturnType<typeof fn>; // boolean type FnParams = Parameters<typeof fn>; // [number, string]
Nuances bij functie-overbelasting: Bij functie-overbelasting definieert ReturnType de laatste variant van de handtekening en Parameters — alle mogelijke overbelastingen:
function overloaded(x: number): number; function overloaded(x: string): string; function overloaded(x: any): any { return x; } type OverRet = ReturnType<typeof overloaded>; // any type OverParams = Parameters<typeof overloaded>; // [any]
Dat wil zeggen, de typering van utility types "ziet" niet altijd alle overbelastingen, waardoor statische typering minder voorspelbaar wordt.
Is het mogelijk om met ReturnType en Parameters de types van alle mogelijke overbelastingen van een aangepaste functie te verkrijgen, door elke overbelasting afzonderlijk te definiëren?
Antwoord:
Nee. De utility types ReturnType en Parameters analyseren alleen de "samengevoegde" handtekening van de functie — zoals deze is beschreven voor de implementatie. Ze laten niet toe om de types van elke individuele overbelasting te verkrijgen — alleen de uiteindelijke gerealiseerde handtekening.
Voorbeeld:
type P = Parameters<typeof overloaded>; // [any], en niet [number], [string]
Verhaal
Ontwikkelaars schreven een wrapper aroundMethod, gebruikmakend van ReturnType<T> voor het typeren van de teruggegeven waarde. De wrapper functie werd toegepast op een overbelaste functie. Het resultaat: de types waren te algemeen (any), en bij fouten signaleerde de compiler geen inconsistentie in de teruggegeven waarden. De bug werd te laat ontdekt bij het werken met booleans in plaats van strings.
Verhaal
In een poging om de parameters voor meerdere API-functies af te leiden via Parameters<T>, houdt de ontwikkelaar geen rekening met de overbelastingen van de methoden. Hierdoor ontstond een probleem met "onjuiste" types, waarbij in plaats van [string, number] [any] werd verwacht. De eenheidstests vingen deze fout niet omdat deze door de implementatie werden gemonteerd, en echte gebruikers van de API kregen bugs in productie.
Verhaal
Bij het migreren van een grote codebase van JavaScript naar TypeScript typiseerden ontwikkelaars alles via ReturnType. Later realiseerden ze zich dat de implementatie sterk verschilde van de declaratie van de overbelastingen. Hierdoor leidden scenario's met onjuiste argumenten tot onverwachte runtime-excepties (bijvoorbeeld, TypeError: x is undefined).