JSON vers TypeScript
Convertir automatiquement les données JSON en interfaces TypeScript ou définitions de type
// Les définitions de type TypeScript seront générées automatiquementQu'est-ce que JSON vers TypeScript ?
JSON to TypeScript analyse une structure JSON et génère des interfaces ou alias de type TypeScript. C’est utile lorsque des réponses d’API, fichiers de configuration, exemples de payload ou données fictives doivent être intégrés rapidement dans un projet frontend ou Node.js typé. L’outil déduit les objets, tableaux, propriétés imbriquées, champs optionnels et types simples, transformant des données brutes en point de départ pour l’autocomplétion et les contrôles à la compilation. Une relecture reste indispensable: un seul exemple JSON peut oublier des champs, les tableaux vides ne décrivent pas leurs éléments et les vraies API peuvent renvoyer null ou plusieurs formes.
Comment utiliser
Comment utiliser
- Collez des données JSON dans la zone de saisie de gauche, ou cliquez sur le bouton d'exemple pour charger un exemple
- Configurez les options : définissez le nom du type racine, choisissez le style interface/type, l'ajout de l'export, etc.
- Les définitions de types TypeScript correspondantes sont générées automatiquement à droite
- Cliquez sur le bouton « Copy » pour copier les définitions de types dans le presse-papiers
- Collez les définitions de types dans votre projet TypeScript pour les utiliser
Conseils pour la génération de types
- Utilisez des échantillons JSON représentatifs. Un seul exemple ne peut pas révéler tous les champs optionnels, les valeurs nullables ni les types union d'une API réelle.
- Vérifiez les noms générés avant de les valider, en particulier pour les objets imbriqués où les noms d'interface automatiques peuvent être trop génériques.
Cas d’utilisation
Principe technique
JSON vers TypeScript est fondamentalement un processus d'« inférence de structure ». L'outil parcourt chaque nœud de l'arbre JSON de manière récursive, associant le type d'exécution de chaque valeur à un type TypeScript : string -> string, number -> number, boolean -> boolean, null -> null, objet -> sous-interface, tableau -> tableau du type de l'élément. La sortie est un ensemble de déclarations `interface` TypeScript (ou d'alias `type` si le mode de sortie 'type' est sélectionné) plus toutes les interfaces imbriquées extraites des champs à valeur d'objet. La partie délicate de l'inférence est la décision union-vs-type-unique pour les tableaux. Lorsque chaque élément d'un tableau a le même type, la sortie est `T[]` (tableau homogène). Lorsque les éléments ont des types différents, la sortie est l'union de ces types : `[1, 'a', true]` devient `(number | string | boolean)[]`. Lorsque l'entrée est un objet qui mélange des valeurs littérales et structurées (par ex. `{ id: 1, name: 'Alice', tags: ['admin', 'editor'] }`), chaque champ obtient son propre type ; pour les objets à valeurs primitives mélangées, la page émet une seule interface, pas une union, car c'est ce que le code TypeScript attend (et cela correspond à la nature de l'objet JSON en tant que type enregistrement). Les objets d'échantillon multiples (le cas d'usage typique : coller un tableau JSON) sont fusionnés par intersection de leurs formes. Les champs présents dans chaque échantillon deviennent requis ; les champs manquants dans un échantillon deviennent optionnels (`fieldName?: T`). C'est le comportement correct pour les réponses API : une réponse 200 OK a une forme, une réponse 404 en a une autre, et l'union des deux est le bon type TS. Pour un seul échantillon, chaque champ est requis. La normalisation des noms est là où la plupart des outils « JSON vers TS » sont défaillants. Les clés JSON sont généralement en snake_case (`user_id`, `created_at`) ou en camelCase (`userId`, `createdAt`) ; la convention TypeScript est PascalCase pour les noms d'interface (`UserProfile`, `AuditEntry`) et camelCase pour les noms de propriétés. La page convertit les clés JSON en camelCase (ou les préserve si elles sont déjà en camelCase ou en un seul mot) et en PascalCase pour les noms d'interface. Les objets internes sont extraits en interfaces nommées : `{ user: { name, age } }` devient `interface User { name: string; age: number; }` et le parent devient `interface Root { user: User; }`. Les structures récursives (un nœud d'arbre avec un champ `children: TreeNode[]`) obtiennent une auto-référence via une déclaration `type` avant rather que `interface` pour que le cycle soit bien défini. Le basculement 'root' fait la différence entre une racine tableau et une racine objet. Un tableau JSON devient `type Root = Item[]` ou `interface Root { items: Item[]; ... }` selon le basculement wrap-array. Un objet JSON devient une interface plate au niveau supérieur. Les chaînes de date (RFC 3339 / ISO 8601) peuvent être marquées comme `Date` au lieu de `string` ; les UUID, emails et URLs peuvent être marqués comme types à marqueur (`type UUID = string & { readonly __brand: 'UUID' };`) lorsque le basculement mode strict est activé. La génération JSDoc est heuristique : un champ nommé `email` (et dont la valeur correspond à une regex email basique) reçoit un commentaire comme `/** user email */` au-dessus de la déclaration. Il en va de même pour `id`, `name`, `url`, `created_at`/`createdAt`, `updated_at`/`updatedAt`, `description`, `title`. Les commentaires sont au mieux et ne prétendent pas être écrits par un humain ; ils sont un point de départ que les humains éditeront. La page émet aussi des modificateurs `export` pour que la sortie puisse être insérée telle quelle dans n'importe quel fichier TS, et un en-tête `// generated by json-to-typescript, do not edit by hand` pour décourager les modifications manuelles qui seraient écrasées à la prochaine régénération du schéma.
- Association de types atomiques : les types string/number/boolean/null de JSON correspondent un à un aux string/number/boolean/null de TypeScript. Les grands entiers (>2^53) nécessitent BigInt ; la page les marque comme `bigint` lorsque la valeur dépasse Number.MAX_SAFE_INTEGER.
- Inférence de type de tableau : parcourt tous les éléments et prend l'union de leurs types ; les types identiques se réduisent en `T[]`, les types distincts forment `(A | B | C)[]`. Les tableaux vides deviennent `unknown[]` puisque le type de l'élément est inconnu.
- Extraction d'objets imbriqués : les objets internes sont automatiquement extraits en interfaces nommées. Les structures récursives utilisent `type Name = ...` (pas `interface`) pour que la référence avant soit bien définie dans le vérificateur de types TypeScript.
- Détection des champs optionnels : lorsque plusieurs objets d'échantillon sont fusionnés, les champs présents dans chaque échantillon deviennent requis ; les champs manquants dans un échantillon deviennent optionnels (`fieldName?: T`). Une entrée à un seul échantillon marque chaque champ comme requis.
- Convention de nommage : les clés JSON sont converties en camelCase pour les noms de propriétés (user_id -> userId, created_at -> createdAt) et en PascalCase pour les noms d'interface (UserProfile, AuditEntry). Les clés en un seul mot sont préservées ; les chiffres dans les clés sont préservés ; les chiffres en tête sont préfixés d'un underscore pour rester des identifiants TS valides.
- Basculement racine : racine tableau -> `export type Root = Item[]` (ou enveloppé dans `{ items: Item[]; }` si wrap-array est activé) ; racine objet -> une seule `export interface Root { ... }`. Les structures récursives obtiennent d'abord un stub de déclaration avant.
- Commentaires JSDoc : génération heuristique de commentaires pour les noms de champs connus (email, id, name, url, createdAt, updatedAt, description, title). La sortie inclut des modificateurs `export` et un en-tête `// generated, do not edit by hand` pour décourager les modifications manuelles.
- Mode strict : activation optionnelle des types à marqueur (UUID, Email, URL, Date), des modificateurs readonly, d'exactOptionalPropertyTypes et de noUncheckedIndexedAccess. La page émet `type UUID = string & { readonly __brand: 'UUID' };` lorsque le mode strict est activé, pour que le code en aval puisse distinguer une chaîne brute d'une valeur typée.
Exemples
Objet simple vers interface
{"id": 1, "name": "Alice", "active": true}
->
interface User {
id: number;
name: string;
active: boolean;
}Un objet imbriqué génère des sous-interfaces
{"user": {"name": "Alice", "address": {"city": "NYC"}}}
->
interface Root {
user: User;
}
interface User {
name: string;
address: Address;
}
interface Address {
city: string;
}Tableau vers tuple readonly
[{"id": 1}, {"id": 2}]
->
interface Item {
id: number;
}
type Root = readonly Item[];FAQ
Quels constructeurs TypeScript génère-t-il ?
Des interfaces par défaut — une par forme d'objet. Les champs optionnels utilisent le marqueur ?. Les tableaux deviennent T[]. Les tableaux de types mixtes deviennent une union. Les chaînes de formats reconnus (par exemple les dates ISO) restent en string sauf si vous activez les types brandés. Certaines pages proposent des alias « type » au lieu d'« interface ».
Comment les objets imbriqués sont-ils traités ?
Chaque forme imbriquée distincte obtient sa propre interface, nommée d'après le chemin de propriété (User, UserAddress, UserPreferences). Si deux propriétés partagent la même forme, le générateur peut ou non dédupliquer selon les paramètres — vérifiez la sortie et regroupez à la main si nécessaire.
Les propriétés sont-elles requises ou optionnelles ?
Par défaut, les propriétés présentes dans l'échantillon sont marquées requises. Les propriétés qui apparaissent dans certains éléments d'un tableau mais pas dans d'autres sont marquées optionnelles avec `?`. Activez « toutes optionnelles » si votre échantillon est un exemple parmi de nombreuses formes possibles.
Comment gère-t-il null et undefined ?
null en JSON devient `null` en TypeScript (pas undefined). Une propriété qui est parfois une chaîne et parfois null devient `string | null`. JSON n'a pas d'undefined, donc le générateur n'émet jamais directement `undefined`.
Et les types union et les unions discriminées ?
Lorsqu'un tableau contient des formes d'objet mixtes, le générateur émet une union d'interfaces. Il ne détecte pas automatiquement un champ discriminant ; réécrivez à la main en union discriminée (par exemple un tag « kind ») si vous voulez un narrowing de type exhaustif.
Le JSON est-il téléversé ?
Non. La conversion s'exécute dans votre navigateur via un analyseur JSON basé sur JS et un template de chaîne. Le JSON collé ne quitte pas votre appareil.
Cela correspondra-t-il à ce que mon backend renvoie réellement ?
Seulement dans la mesure où l'échantillon est représentatif. Validez toujours les données à l'exécution avec un schéma (Zod, io-ts, Yup) — les types TypeScript sont effacés à l'exécution et ne détecteront pas un backend qui dérive de l'exemple.