FAQ
Are nested objects turned into separate interfaces?
Optional. Expand mode generates an interface per nested object; inline mode keeps them inside the parent.
How are array types written?
Both T[] and Array<T> styles are supported, pick whichever your project uses.
How is the optional marker decided?
A field is marked optional when it is missing from some elements of an array. Inconsistent samples therefore produce looser types.
About this tool
Turns a JSON sample into TypeScript type definitions. Two switches decide the shape: nested objects either expand into separate interfaces or stay inline as { a: string }, and arrays can render as T[] or Array<T>. The root interface name is editable.
Three things that actually break generated code, all handled here:
- Keys that are not valid identifiers need quotes.
{"user-name": 1}must produce"user-name": number;; emittinguser-name: number;is a syntax error, which is exactly what many online converters do. - Optional fields come from array membership.
[{"id":1,"name":"a"},{"id":2}]yieldsname?: string;because the second element has no name. That is a detectable rule rather than a guess: a key present in every element is required, one missing anywhere is optional. - Same-named objects with different shapes are not merged. When
data.addressandmeta.addressdiffer, you getAddressandAddress2instead of the second one being silently dropped.
Other behaviour: array element types are unioned, so [1,"a"] becomes (number | string)[]; an empty array is unknown[]; a null value types as null (and unions with siblings as string | null); an array root emits type Root = Item[] plus interface Item.
What it does not do: it does not infer literal unions such as "new" | "done" (that needs samples covering every value), it does not generate runtime validation (use zod or io-ts for that), it does not merge structurally similar objects, and every number becomes number - so JSON containing integers above 2^53 (an 18-digit order id, say) loses precision and should be typed as string by hand.
One distinction worth keeping: name?: string means the key may be absent, while name: string | null means it is always present but may be null. A JSON null is the latter, which is why this tool emits | null.