Achtergrond
Met de ontwikkeling van TypeScript ontstond de noodzaak om automatisch het type van de retourwaarde van een functie te extraheren, vooral voor grote projecten met veel onderling verbonden functies. Hiervoor werd het hulptype ReturnType<T> geïntroduceerd, dat beschikbaar kwam in de standaardbibliotheek vanaf versie TypeScript 2.8.
Probleem
In grote en complexe projecten kan het moeilijk zijn om de types actueel te houden — als je handmatig het type van de retourwaarde van elke functie opgeeft en de handtekeningen wijzigt, kan er gemakkelijk een inconsistentie ontstaan wanneer de handtekeningen en implementaties niet overeenkomen. Bovendien, als een functie een complexe structuur retourneert, is het niet altijd eenvoudig om de beschrijving van het teruggegeven type handmatig in alle gebruiksplaatsen te synchroniseren.
Oplossing
Het hulptype ReturnType<T> extrahert automatisch het retourtype van functies en kan worden gebruikt voor het typeren van het resultaat van een functieaanroep op elke plek in de code. Dit vermindert de hoeveelheid handmatige onderhoud aan de type-infrastructuur en minimaliseert fouten die verband houden met inconsistentie tussen het beschreven en feitelijke retourtype.
Voorbeeldcode:
function createUser(name: string, age: number) { return { name, age, created: new Date() }; } type User = ReturnType<typeof createUser>; // User: { name: string; age: number; created: Date; }
Belangrijkste kenmerken:
Kan ReturnType worden gebruikt met klasse-methoden?
Ja, maar het is belangrijk om rekening te houden met de context: als de methode een eigenschap van een object is met een functie, gebruik dan ReturnType<obj['methode']>.
Voorbeeldcode:
class MyClass { foo(x: number) { return x * 2; } } type FooReturn = ReturnType<MyClass['foo']>; // Type-error! // Het moet zijn: type FooReturn = ReturnType<(x: number) => number>; // number // Of de methode als functie buiten de klasse plaatsen: const obj = new MyClass(); type FooReturn2 = ReturnType<typeof obj.foo>;
Wat zal ReturnType teruggeven voor functies met void/never?
Voor een functie met een opgegeven type void, zal ReturnType void teruggeven. Voor never — never.
Voorbeeldcode:
function doNothing(): void {} type Result = ReturnType<typeof doNothing>; // void
Werkt ReturnType met functie-overbelastingen?
Nee, ReturnType extraheert het retourtype van de "implementatie" zelf, niet van alle overbelastingen. Als er meerdere overbelastingen zijn, wordt het beschreven type van de implementatie genomen.
Voorbeeldcode:
function func(x: number): number; function func(x: string): string; function func(x: any): any { return x } type RT = ReturnType<typeof func>; // any
In een project wordt een handmatig type voor het teruggegeven object van een functie gedeclareerd. De functie verandert — het type wordt niet bijgewerkt, aanroepen falen in runtime.
Voordelen:
Nadelen:
Ze schakelen overal over naar ReturnType waar ze waarden gebruiken die door functies worden geretourneerd. In geval van wijzigingen is het type altijd actueel.
Voordelen:
Nadelen: