Jak działa wnioskowanie JSON do TypeScript?
Wnioskowanie to pojedynczy przebieg przez przetworzone drzewo JSON. Narzędzie odczytuje każdą wartość, wybiera dla niej typ TypeScript, a następnie zapisuje jeden interfejs na każdy znaleziony obiekt.
- Parsuj próbkę JSON natywnym parserem przeglądarki i odrzucaj zniekształcone dane wejściowe z podpowiedzią wiersza/kolumny.
- Wykryj typ TypeScript dla każdej wartości —
string,number,boolean,null, tablica lub zagnieżdżony obiekt. - Nadaj każdemu zagnieżdżonemu obiektowi nazwę interfejsu wywodzoną z klucza właściwości rodzica (więc
user.addressstaje się interfejsemAddress). - Scalaj typy elementów po każdej tablicy, by lista
{id: 1}i{id: 2, label: "x"}produkowała unię z właściwymi opcjonalnymi polami. - Zastosuj opcje (interface vs. type, readonly, opcjonalny-nullable) i emituj deklaracje w kolejności zależności, by plik kompilował się bez odwołań do przyszłości.
Dlaczego generować typy TypeScript z JSON?
- Większość błędów kształtu jest łapalna w czasie kompilacji, jeśli typ odpowiedzi jest zapisany. Wywnioskowanie interfejsu z prawdziwego payloadu zapisuje większość za Ciebie, a tryb `strict` łapie pole, o którym dokumentacja zapomniała wspomnieć.
- Parowanie wywnioskowanych interfejsów z walidatorem runtime jak Zod lub io-ts daje temu samemu kształtowi dwie prace: autouzupełnianie edytora podczas deweloperki i błąd 400 na krawędzi gdy produkcja wyśle coś nieoczekiwanego.
- Serwer językowy TypeScript pokazuje tylko pola, o których wie. Gdy zaimportujesz wywnioskowany interfejs, autouzupełnianie działa w momencie wpisania kropki — koniec z rzutowaniem `as any` na odpowiedź i sfrustrowanym grepowaniem po repozytorium.
- Jeśli zamierzasz napisać specyfikację OpenAPI, wywnioskowany interfejs to szybki pierwsza wersja robocza schematu odpowiedzi. Nadal będziesz chciał ręcznie pisane przykłady i ograniczenia, ale nazwy właściwości i typy są już poprawne.
Typowe zastosowania
Wnioskowanie pomaga najbardziej gdy prawdziwy payload istnieje, ale schemat nie.
- Typowanie webhooków firm trzecich od Stripe, GitHub lub Twilio przed napisaniem handlera.
- Bootstrapowanie typów dla wewnętrznego API REST, by zespół front-endu mógł zacząć kodować względem niego tego samego dnia gdy backend wyląduje.
- Generowanie punktu startowego dla schematu Zod, io-ts lub Valibot z obserwowanej odpowiedzi API.
Jak wygląda wynik?
Dla przykładowego dokumentu JSON i nazwy roota generator produkuje drzewo interfejsów, jeden na zagnieżdżony obiekt. Dla poniższego wejścia z nazwą roota User:
Wklej {"id":1,"name":"Alice","tags":["a","b"],"address":{"city":"Paris"}} z nazwą roota User a generator produkuje:
export interface User {
id: number;
name: string;
tags: string[];
address: Address;
}
export interface Address {
city: string;
}
Zauważ, że address zostało awansowane do własnego nazwanego interfejsu — to wynik w kolejności zależności. Ten sam JSON ze stylem deklaracji type zamiast emitowałby export type User = {...}; z włączonym przełącznikiem readonly każda właściwość dostaje modyfikator readonly.
Opcje generatora
Styl deklaracji
Wybierz interface (standardowy idiom TypeScript dla kształtów obiektów) lub type (przydatny gdy będziesz potrzebować typów mapowanych, warunkowych lub przecięć później). Oba produkują identyczne zachowanie runtime; wybór to preferencja stylu kodowania.
Opcjonalne pola dopuszczające null
Gdy próbkowana wartość to null, typ pola staje się T | null. Włączenie tej opcji dodaje też modyfikator ?, więc pole jest opcjonalne po stronie TypeScript — przydatne gdy API czasem całkowicie pomija klucz zamiast zwracać null.
Modyfikator readonly
Dołącza readonly do każdej deklaracji właściwości, by emitowany interfejs pasował do niezmiennego modelu danych. Przydatne dla wycinków stanu Redux, zamrożonych odpowiedzi API lub wszędzie gdzie chcesz, by kompilator flagował przypadkowe mutacje.
Czy obsługuje zagnieżdżone obiekty i tablice?
Tak. Każdy zagnieżdżony obiekt staje się nazwanym interfejsem wywiedzionym z klucza właściwości rodzica, a tablice wnioskują typ elementu ze swojej zawartości. Tablice obiektów dostają interfejs na kształt obiektu, z typami unii tam gdzie kształty się różnią.
Jak są wnioskowane opcjonalne pola?
Włącz przełącznik "Oznacz pola dopuszczające null jako opcjonalne" a każde pole, którego próbkowana wartość to null, dostaje modyfikator ? na kluczu plus | null w typie. Bez przełącznika pole pozostaje wymagane a typ to tylko T | null.
Czy obsługuje dyskryminowane unie?
Podstawowe typy unii wychodzą gdy tablica zawiera elementy o mieszanych kształtach lub gdy pole niesie zarówno wartość jak i null. Pełne wnioskowanie dyskryminowanych unii (wybieranie type lub kind jako tagu i dzielenie wariantów) wymaga wielu próbek — jest zaplanowane, ale nie w dzisiejszej wersji.
Czy mogę wnioskować typy z wielu próbek JSON?
Jeszcze nie — dzisiejsze wnioskowanie czyta jedną próbkę na raz. Jeśli masz dwa payloady które powinny dzielić interfejs (powiedzmy endpoint listy i endpoint pojedynczego elementu), praktycznym obejściem jest scalenie ich w jedną tablicę, wygenerowanie z tego i zmiana nazw wynikowych typów unii. Wnioskowanie z wielu próbek jest na mapie drogowej, bo to jedyny sposób na wykrycie pól obecnych w jednej odpowiedzi a nieobecnych w innej.
Wklej payload, nazwij root, skopiuj interfejsy. Cały potok działa w przeglądarce, więc nieudostępniony API lub podpisane ciało webhooka zostaje na Twoim komputerze.