JSON to TypeScript – Generate Interfaces from Real API Responses
Typing an API response by hand is slow and easy to get wrong. This JSON to TypeScript converter reads a sample of real data, such as an API response, a config file or a log line, and writes the TypeScript interfaces that describe it. Each nested object gets its own named declaration. Arrays, unions, optional properties and null are all worked out from the data. The result is ready to paste into your codebase, and all of it runs in your browser.
From one sample to many: how the types are inferred
The generator folds every value it sees into a shape: one record per position in the document that counts how often each kind of value appeared. All items of an array share one shape, so a list of 500 orders becomes a single Order type, not 500. You can also paste several responses one after another, or a JSON Lines file (.jsonl, .ndjson), and they are merged the same way. More samples give more accurate types.
- A key that some objects lack becomes optional:
giftWrap?: boolean. - A value that is sometimes
nullbecomesT | null. Missing andnullare different at runtime, so the tool keeps them apart. A key that is both prints asphone?: string | null. - Mixed values become a union in a fixed order, for example
string | number, so the output stays the same when you reorder your samples. - Objects keyed by numeric IDs, UUIDs or dates are detected as maps and typed as
Record<string, User>instead of an interface with one property per ID.
Readable names, no clashes
Type names come from property keys. shipping_address becomes ShippingAddress, and the items of an array are singularized, so line_items becomes LineItem and categories becomes Category. When two different shapes ask for the same name, the second one is prefixed with its parent (CompanyAddress). Names that would clash with built-in types such as Date, Response or Event are prefixed too, because an interface Date in a script silently merges with the global Date. Identical shapes share one declaration, and any type can be renamed in the Types tab. Every reference follows the new name.
shipping_address as it is instead of converting it to camelCase. A renamed property would describe an object that JSON.parse never returns.See the structure, then check the gaps
The type diagram draws each declared type as a box, with arrows to the types it references. Optional fields show their coverage, for example 1/2, meaning the key appeared in one of the two objects seen at that position. That answers the usual question "why is this optional?". The Notes tab lists what a person should review before trusting the output:
- Fields that were
nullin every sample and arrays that were always empty. These are typedunknownbecause the data says nothing about them. - Fields that mix types, such as an ID that is sometimes a number and sometimes a string.
- Integers above
Number.MAX_SAFE_INTEGER(9007199254740991), such as 64-bit IDs, whichJSON.parsesilently rounds. They also get a JSDoc warning in the output. - Duplicate keys, detected maps and types renamed to avoid a clash.
Output options
Choose interface or type declarations, separate or inline nested types, T[] or Array<T>, readonly properties, 2 or 4 spaces or tabs, and unknown or any for fields with no information. You can also add example values as JSDoc comments, or turn enum-like strings into literal unions such as "admin" | "editor". Comments and trailing commas, common in tsconfig.json-style files, are accepted by default.