Typer une fonction basée sur OpenApi

Voir la vidéo

Dans ce tutoriel je vous propose d'explorer un peu plus en profondeur les capacités de Typescript pour voir comment créer un type avancé basé sur une définition OpenApi.

L'objectif

L'objectif est de créer une fonction qui va appeler l'API et nous renvoyer les résultats. La signature ressemblera à ça fetchAPI(baseUrl, endpoint, options) et on souhaite que Typescript vérifie les paramètres :

  • endpoint devra correspondre à un point d'entrée de notre API
  • options.method ne pourra pas être invalide
  • options.query devra être un objet qui correspond à ce qu'accepte l'API au niveau des query parameters
  • options.params permettra d'ajouter des paramètres dans l'URL (si le endpoint est /post/{id} par exemple on s'attendra à ce que id soit requis)
  • options.json devra être rempli si la requête attend un corps en application/json.
  • La réponse devra automatiquement être typée en fonctions des paramètres reçus.

On veut tant que possible automatiser cette déclaration en partant d'une interface qui sera générée par openapi-typescript depuis notre fichier de définition OpenAPI

La solution

Pour arriver à obtenir le résultat souhaité nous allons devoir utiliser quelques fonctionnalités avancé du Typescript.

Les generics vont permettre de créer des types qui vont avoir en paramètre d'autres types. Par exemple, les méthodes possibles dépendront du path :

type MethodsForPath<P in keyof paths> = keyof paths[P]

Les types conditionnels vont permettre de vérifier si une clef existe dans l'interface pour ajouter une condition définie.

type SuccessResponseBody<P> = P extends {responses: {"200": {"application/json": infer T}}} ? T : undefined

On pourra aussi s'aider de types utilitaires pour éviter la répétition.

// Trouve le type d'une valeur en profondeur dans un object Get<obj, ["player", "firstname"]>
type Get<T extends any, K extends any[], D = never> = K extends []
    ? T
    : K extends [infer A, ...infer B]
    ? A extends keyof T
        ? Get<T[A], B>
        : D
    : D;

Voici le type obtenu pour notre fonction fetchAPI (le code pourra être amélioré avec le temps).

Pour s'améliorer

Si vous voulez améliorer vos capacités à typer votre code, vous pouvez essayer les types-challenges qui vous proposent une série d'exercices organisés par niveau pour pratiquer.

Publié
Technologies utilisées
Auteur :
Grafikart
Partager