JSON vers TypeScript
Générez des interfaces TypeScript à partir d’un exemple JSON.
À propos de cet outil
Collez une réponse JSON et obtenez les interfaces TypeScript correspondantes. Les objets imbriqués deviennent des interfaces nommées distinctes, les tableaux d’objets sont fusionnés pour que les champs facultatifs soient marqués d’un ?, et les valeurs mixtes deviennent des types union.
Mode d’emploi
- Collez un exemple de réponse JSON de votre API.
- Définissez le nom du type racine, par exemple User ou OrderResponse.
- Choisissez des déclarations interface ou type, et indiquez s’il faut les exporter.
- Copiez le TypeScript généré dans votre projet et ajustez ce que l’exemple ne pouvait pas montrer.
Questions
- Comment les champs facultatifs sont-ils détectés ?
- Quand un tableau contient plusieurs objets, un champ absent de certains d’entre eux est marqué comme facultatif avec ?. Un objet unique ne peut pas révéler les champs facultatifs : fournissez si possible un exemple avec plusieurs éléments.
- Pourquoi un champ est-il typé null ?
- Parce qu’il valait null dans l’exemple, son type réel est donc inconnu. Remplacez-le par quelque chose comme string | null une fois que vous savez ce que renvoie l’API.
- Faut-il utiliser interface ou type ?
- Les deux conviennent pour décrire du JSON. Les interfaces peuvent être étendues et fusionnées, et donnent des messages d’erreur un peu plus clairs ; les alias de type sont nécessaires pour les unions. Choisissez ce que votre code utilise déjà.
- Valide-t-il les données à l’exécution ?
- Non. Les types TypeScript disparaissent à la compilation. Pour vérifier des données à l’exécution, utilisez une bibliothèque de schémas comme Zod en complément de ces types.
- Que se passe-t-il si la racine du JSON est un tableau ?
- La racine devient un alias de type pour un tableau. Avec le nom racine User et un exemple comme [{"id": 1}], vous obtenez type User = UserItem[] ainsi qu’une interface UserItem pour les éléments. Donnez à la racine un nom au pluriel, comme Users, pour obtenir plutôt type Users = User[].
- Peut-on coller un objet JavaScript au lieu de JSON strict ?
- Oui. Les guillemets simples, les clés sans guillemets, les virgules finales et les True, False et None de Python sont convertis en JSON avant la génération des types : une sortie copiée depuis console.log dans Node ou depuis un shell Python fonctionne donc. Les valeurs que JSON ne peut pas exprimer, comme les fonctions ou les instances de classe, provoquent toujours une erreur.
- Pourquoi le type des éléments d’un tableau s’appelle-t-il DataItem ?
- Les types d’éléments sont nommés en mettant la clé du tableau au singulier : users donne User et entries donne Entry. Quand une clé n’a pas de terminaison de pluriel, comme data ou children, Item est ajouté à la place, ce qui donne DataItem et ChildrenItem. Renommez-les dans votre éditeur après les avoir collés si vous préférez d’autres noms.
Comment générer des interfaces TypeScript à partir de JSON ?
Collez une vraie réponse d’API, et chaque objet JSON devient une interface TypeScript nommée. Les noms de champs sont conservés, les valeurs sont traduites en string, number et boolean, et un objet imbriqué reçoit sa propre déclaration, nommée d’après sa clé : un champ address produit ainsi une interface Address. Les tableaux d’objets sont nommés au singulier : orders donne Order[] et categories donne Category[]. Choisissez comme nom racine le type que votre code utilisera, par exemple User.
Le TypeScript généré compile tel quel : vous pouvez le coller dans un fichier types.ts ou le télécharger. Les clés qui ne sont pas des identifiants valides, comme "first-name" ou "2fa", sont écrites entre guillemets. Quand deux objets imbriqués recevraient le même nom, le second reçoit un numéro, comme Address2. Un tableau vide devient unknown[] et un objet vide devient Record<string, unknown>, car l’exemple n’indique rien sur leur contenu.
Comment les types union sont déduits du JSON
Quand un même champ contient des valeurs de natures différentes, son type devient une union. Un tableau comme [1, "two", null] est typé (string | number | null)[], et un champ qui est une chaîne dans un élément et un nombre dans un autre devient string | number. Les objets d’un même tableau sont fusionnés en une seule interface plutôt qu’en une union de formes, et les champs présents dans certains d’entre eux seulement sont marqués comme facultatifs.
La fusion convient aux listes d’enregistrements, mais elle masque les unions discriminées. Si un tableau events mélange {"type": "click", "x": 3} et {"type": "key", "code": "Enter"}, vous obtenez une seule interface Event, avec type en string et x et code tous deux facultatifs. Réécrivez-la à la main sous forme d’union discriminée de deux interfaces, l’une avec type: "click" et l’autre avec type: "key", pour que TypeScript puisse affiner le type grâce au champ type.
JSON vers TypeScript : à partir d’un exemple ou d’un schéma ?
Un exemple JSON montre une réponse, pas le contrat. Les chaînes qui sont en réalité des dates, les enums comme "active" | "banned", les identifiants numériques qui peuvent dépasser 2^53 et les champs présents seulement de temps en temps sont invisibles dans un seul exemple. Considérez les interfaces générées comme un premier jet : collez une réponse avec plusieurs éléments de tableau, puis resserrez les types là où vous en savez plus, par exemple en remplaçant status: string par une union des valeurs autorisées.
Si une API publie un document OpenAPI ou un JSON Schema, générez plutôt les types à partir de celui-ci, car il décrit chaque champ que le serveur peut renvoyer. Générer des types à partir de JSON est la solution rapide pour les API tierces sans spécification, les payloads de webhooks et les anciens endpoints internes. Pour les données que vous ne contrôlez pas, ajoutez une vérification à l’exécution de même forme, comme un schéma Zod, pour qu’une réponse modifiée échoue bruyamment au lieu de passer inaperçue.
Quelque chose ne fonctionne pas, ou un résultat semble faux ? Signaler un problème avec cet outil