How this converter works
The generator walks your JSON value by value and builds a type tree. Objects become interfaces (or type aliases), arrays merge the shape of every element, and a key that appears in one array element but not another is marked optional with a question mark. A null alongside a string becomes string | null instead of silently disappearing.
One response rarely shows every field, so you can paste several samples at once — JSON Lines, or objects one after another — and they are merged exactly like array elements. Turn on “Top-level array = samples” to type the elements of a list response instead of the list. With “String literals” on, a field like status that keeps repeating a handful of values becomes "paid" | "refunded"; “Detect formats” and “Example values” add JSDoc hints for ISO dates, emails, URLs and UUIDs.
The Types + guards target adds a dependency-free isRoot(value): value is Root function per type, so you can check a fetch() result at runtime. The JSON Schema target writes draft 2020-12 with $defs, required lists, enum and format keywords. Types inferred from samples are a starting point, not a contract — a field present in every sample may still be absent in production.
Frequently asked
Can it infer optional fields?
Yes, when a key is missing from at least one sample — an element of an array, or one of several samples pasted as JSON Lines. A field present in every sample is required, because the samples can't prove it is ever absent. Enable “Optional as ?: T | undefined” if your project uses exactOptionalPropertyTypes.
What happens with mixed-type arrays?
The element type becomes a union, such as (string | number)[]. Objects in the same array are merged field by field, with missing keys marked optional.
interface or type alias — which should I pick?
They are interchangeable for JSON shapes. Interfaces give clearer error messages and can be extended with declaration merging; type aliases are what you need if you plan to combine the result with unions or mapped types. Switch with “Declare objects as”.
Why is a null-only field typed as unknown?
A field that is null in every sample says nothing about the type it has when it is set. unknown forces you to check it before use; pick null or any under “Always-null fields” if you prefer, or paste a sample where the field has a value.
Does it generate runtime validation?
Yes — the Types + guards target writes plain TypeScript type-guard functions with no dependencies. For schema-based validation with error messages, use the JSON Schema target with Ajv, or the JSON to Zod converter.