ReturnType<T> et Parameters<T> sont des types utilitaires de TypeScript qui permettent d'extraire automatiquement le type de valeur de retour d'une fonction (ReturnType) ou un tableau des types de ses paramètres (Parameters).
C'est particulièrement utile pour garantir la cohérence des types entre différentes parties de l'application et pour mettre en œuvre des wrappers génériques.
Exemple d'utilisation :
function fn(a: number, b: string): boolean { return b.length > a; } type FnReturn = ReturnType<typeof fn>; // boolean type FnParams = Parameters<typeof fn>; // [number, string]
Subtilités avec la surcharge des fonctions : Lors de la surcharge des fonctions, ReturnType détermine la dernière variante de la signature, tandis que Parameters — toutes les surcharges possibles :
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]
Ainsi, la typisation des types utilitaires ne « voit » pas toujours toutes les surcharges, ce qui rend la typisation statique moins prévisible.
Peut-on utiliser ReturnType et Parameters pour obtenir les types de toutes les surcharges possibles d'une fonction personnalisée, en définissant chaque surcharge individuellement ?
Réponse :
Non. Les types utilitaires ReturnType et Parameters n'analysent que la signature « combinée » de la fonction — telle qu'elle est décrite pour l'implémentation. Ils ne permettent pas d'obtenir les types de chaque surcharge individuelle — uniquement ceux de la signature finale mise en œuvre.
Exemple :
type P = Parameters<typeof overloaded>; // [any], et non [number], [string]
Histoire
Les développeurs ont écrit un wrapper aroundMethod, en utilisant ReturnType<T> pour typiser la valeur de retour. Cependant, la fonction wrapper était appliquée à une fonction surchargée. Résultat : les types étaient trop généraux (any), et lors d'erreurs, le compilateur ne signalait pas de discordances de valeurs retournées. Un bug a été découvert tardivement lors du passage de boolean à string.
Histoire
En essayant d'extraire les paramètres pour de nombreuses fonctions API via Parameters<T>, le développeur n'a pas pris en compte les surcharges des méthodes. Un problème de types « erronés » est apparu, où [string, number] était attendu au lieu de [any]. Les tests unitaires n'ont pas détecté cette erreur en raison du montage via l'implémentation, et les véritables utilisateurs de l'API ont rencontré des bugs en production.
Histoire
En migrant un gros code de JavaScript vers TypeScript, les développeurs ont typisé tout à l'aide de ReturnType. Ils ont ensuite réalisé que l'implémentation différait considérablement de la déclaration des surcharges. Cela a entraîné des scénarios avec des arguments erronés provoquant des exceptions runtime inattendues (par exemple, TypeError: x is undefined).