Écrire des types TypeScript à la main pour une réponse JSON que vous avez déjà est répétitif et facile à faire subtilement mal au premier coup, surtout quand un champ est optionnel ou qu'une valeur est imbriquée à trois niveaux de profondeur.
Utilisation du générateur JSON vers TypeScript
Collez un document, ou plusieurs enregistrements dans un tableau, nommez le type racine, choisissez des interfaces ou des alias de type, et appuyez sur Générer types. L'inférence de type est partagée avec le générateur de schéma sur ce site, donc les deux pages sont d'accord sur ce que votre document contient réellement et ne diffèrent que dans la façon d'écrire la réponse.
Étant
[
{"user": {"name": "a"}, "tags": [], "meta": {}},
{"user": {"name": "b"}, "tags": ["x"], "meta": {}, "extra": true}
]
la sortie est :
export interface RootItem {
user: User
tags: string[]
meta: Record<string, unknown>
extra?: boolean
}
export interface User {
name: string
}
export type Root = RootItem[]
Pourquoi les objets imbriqués obtiennent leur propre type nommé
Un type en ligne à trois niveaux de profondeur est illisible, et rien
d'autre dans le fichier ne peut s'y référer. Les noms viennent de la clé
qui contient l'objet, singularisée dans un tableau (RootItem de Root),
et un nom répété reçoit un numéro attaché pour que la sortie compile
toujours sans collision.
Ce que la marque optionnelle promet réellement
extra?: boolean signifie que la clé manquait dans au moins un
enregistrement dans votre échantillon, exactement la même règle que le
générateur de schéma utilise pour required. Cela ne signifie pas que le
champ est garanti optionnel dans toute votre API, seulement que votre
échantillon ne peut pas prouver qu'il est toujours présent. Lisez la
marque comme une preuve de vos données, pas comme une garantie du système
source.
Valeurs vides
Un objet vide devient Record<string, unknown> plutôt qu'une interface vide,
car une interface vide accepte tout et ne dit rien d'utile sur la forme. Un
tableau vide devient unknown[], car il n'y a rien à l'intérieur dont on
puisse déduire un type d'élément, et en inventer un serait une supposition
déguisée en fait.
Pourquoi chaque nombre est juste number
TypeScript n'a pas de type entier séparé, donc un champ qui est toujours
un nombre entier dans votre échantillon est quand même tapé number, le
même qu'un qui contient des décimales. Cela reflète comment TypeScript modélise
les nombres lui-même, donc les types générés compilent et se comportent
exactement comme des types écrits à la main.