Cum funcționează inferența JSON în TypeScript
Inferența este o singură trecere peste arborele JSON parsata. Instrumentul citește fiecare valoare, alege un tip TypeScript pentru ea și apoi scrie câte o interfață pentru fiecare obiect găsit.
- Parsează eșantionul JSON cu analizorul nativ al browserului și respinge intrarea malformată cu un indiciu de linie/coloană.
- Detectează un tip TypeScript pentru fiecare valoare —
string,number,boolean,null, tablou sau obiect imbricat. - Atribuie fiecărui obiect imbricat un nume de interfață derivat din cheia proprietății părinte (astfel încât
user.addressdevine o interfațăAddress). - Îmbină tipurile elementelor din fiecare tablou, astfel încât o listă de
{id: 1}și{id: 2, label: "x"}produce o uniune cu câmpurile opționale corecte. - Aplică opțiunile (interface vs. type, readonly, opțional-nullabil) și emite declarațiile în ordinea dependențelor, astfel încât fișierul să compileze fără referințe înainte.
De ce să generezi tipuri TypeScript din JSON?
- Majoritatea erorilor de formă sunt prinse la compilare dacă tipul răspunsului este scris. Inferarea unei interfețe dintr-o sarcină reală scrie cea mai mare parte pentru tine, iar modul
strictprinde câmpul pe care documentația a omis să îl menționeze. - Asocierea interfețelor inferate cu un validator de execuție precum Zod sau io-ts oferă aceleiași forme două sarcini: autocompletare în editor în dezvoltare și un 400 la graniță când producția trimite ceva neașteptat.
- Serverul de limbaj TypeScript afișează doar câmpurile despre care știe. Odată ce importați interfața inferată, autocompletarea funcționează imediat ce tastați punctul — nu mai există
as anype răspuns și o căutare frustrantă în depozit. - Dacă urmează să scrii o specificație OpenAPI, o interfață inferată este o primă schiță rapidă a schemei de răspuns. Vei dori totuși exemple și constrângeri scrise manual, dar numele proprietăților și tipurile sunt deja corecte.
Aplicații comune
Inferența ajută cel mai mult când o sarcină reală există, dar o schemă nu.
- Tipizarea sarcinilor webhook de la terți de la Stripe, GitHub sau Twilio înainte de a scrie un handler.
- Inițializarea tipurilor pentru un API REST intern, astfel încât echipa frontend să poată începe să codeze pe baza lui chiar în ziua în care backend-ul este lansat.
- Generarea unui punct de plecare pentru o schemă Zod, io-ts sau Valibot dintr-un răspuns API observat.
Cum arată rezultatul?
Având un document JSON eșantion și un nume de rădăcină, generatorul produce un arbore de interfețe, câte una per obiect imbricat. Pentru intrarea de mai jos cu numele rădăcină User:
Lipește {"id":1,"name":"Alice","tags":["a","b"],"address":{"city":"Paris"}} cu numele rădăcină User și generatorul produce:
export interface User {
id: number;
name: string;
tags: string[];
address: Address;
}
export interface Address {
city: string;
}
Observă că address a fost promovat la propria sa interfață denumită — aceasta este ieșirea ordonată pe dependențe. Același JSON cu stilul de declarație type ar emite export type User = {...}; cu comutatorul readonly activat, fiecare proprietate primește modificatorul readonly.
Opțiuni generator
Stilul declarației
Alege interface (idiomul standard TypeScript pentru forme de obiecte) sau type (util dacă vei avea nevoie de tipuri mapate, tipuri condiționale sau intersecții ulterior). Ambele produc același comportament la execuție; alegerea este o preferință de stil de cod.
Câmpuri opționale nullabile
Când o valoare eșantionată este null, tipul câmpului devine T | null. Activarea acestei opțiuni adaugă și un modificator ? astfel încât câmpul să fie opțional pe partea TypeScript — util când API-ul omite uneori cheia în întregime în loc să returneze null.
Modificatorul readonly
Antepune readonly fiecărei declarații de proprietate, astfel încât interfața emisă să corespundă unui model de date imutabil. Util pentru felii de stare Redux, răspunsuri API înghețate sau oriunde dorești ca compilatorul să semnaleze mutațiile accidentale.
Suportă obiecte imbricate și tablouri?
Da. Fiecare obiect imbricat devine o interfață denumită derivată din cheia proprietății părinte, iar tablourile inferă tipul elementului din conținutul lor. Tablourile de obiecte primesc câte o interfață pe formă de obiect, cu tipuri uniune acolo unde formele diferă.
Cum sunt inferate câmpurile opționale?
Activează comutatorul „Marchează câmpurile nullabile ca opționale” și orice câmp a cărui valoare eșantionată este null primește un modificator ? pe cheie plus | null în tip. Fără comutator, câmpul rămâne obligatoriu și tipul este doar T | null.
Suportă uniuni discriminate?
Tipurile de uniune de bază apar atunci când un tablou conține elemente de forme mixte sau când un câmp poartă atât o valoare, cât și null. Inferența completă a uniunilor discriminate (selectând type sau kind ca etichetă și împărțind variantele) necesită mai multe eșantioane — este planificată, dar nu în versiunea de astăzi.
Pot infera tipuri din mai multe eșantioane JSON?
Încă nu — generatorul de astăzi citește un eșantion odată. Dacă ai două sarcini care ar trebui să partajeze o interfață (de exemplu, un endpoint de listă și unul de element individual), soluția practică este să le îmbini într-un singur tablou, să generezi din acesta și apoi să redenumești tipurile uniune rezultate. Inferența multi-eșantion este pe foaia de parcurs, deoarece este singura modalitate de a depista câmpurile prezente într-un răspuns și absente în altul.
Lipește o sarcină, denumește rădăcina, copiază interfețele. Întregul pipeline rulează în browserul tău, astfel încât un API nelansat sau un corp webhook semnat rămâne pe mașina ta.