JSON to TypeScript

Turn a JSON sample into TypeScript interfaces, with nested objects and arrays split into their own types.

Objects, arrays and nesting are supported. Field order is preserved.

Used for names like Root and RootItem

Shortcuts
Output options
Interfaces0
Total lines0

    

How to use

  1. Paste a JSON response into the box, or press Load sample to see the output first.
  2. The root type name sets the outer interface. Nested objects append the field name, as in RootAddress.
  3. When an array holds objects, their fields merge into one interface and missing keys become optional.
  4. Tick readonly to add the modifier to every field, which suits generated config types.
  5. Copy the result into a .ts file or a declaration file and it is ready to use.

FAQ

What happens when array items differ?
Objects in the same array merge their fields. A key that appears in only some items becomes optional, and its type is the union of every value seen. The generated interface covers all items without failing on the ones that omit a field.
How are null and empty arrays handled?
null becomes the null type. An array holding both objects and null becomes a union of the interface and null. An empty array has nothing to infer, so it outputs unknown[]; add a sample or edit the type by hand.
Why are numbers typed as number?
Every JSON number becomes number with no literal inference. Values like 1, 2 and 3 may come from an enum, and guessing literals would narrow the type too far. number stays safe and you can switch to a union later.
Is my JSON uploaded?
No. Parsing and generation run in the browser, and both input and output live only on this page. A refresh clears them, and nothing is written to local storage.

How to use

  1. Paste real JSON

    Drop a full API response or config file into the box. The closer the sample is to production data, the better the inferred types.

  2. Name the root type

    The root name sets the outer interface. Nested objects append the field name, as in RootAddress and RootOrdersItem.

  3. Pick the output options

    Tick export when the types are shared with other modules. Add readonly for config data and the output updates immediately.

  4. Review optional fields

    Keys missing from some array items get a question mark. Confirm those fields are genuinely optional rather than a one-off gap in the sample.

  5. Copy into the project

    Press copy and paste into a .ts file. The output is a starting point; field meaning and unions still need a human pass.

About this tool

A JSON response is just data until every field has a type. Hand-written interfaces miss keys and fall out of sync the moment a field is renamed, leaving the front end to guess the shape. Paste a real response once and nested objects and arrays split into separate interfaces with the original names and order preserved. The result drops straight into a project, removes a round of mechanical typing, and gives the team one shared description of the payload.

The page parses the JSON into memory, then infers each value recursively. Objects inside an array merge their keys, keys missing from some items become optional, and every type seen contributes to a union. null stays null, and an empty array yields unknown[]. The readonly and export options change the output style, and the root name decides the outer interface. Everything runs in the browser, nothing is uploaded, and closing the page clears both sides.

How it works

Inference only sees the sample. A response without null will produce a type without null, even though production may return an empty value. Numbers always become number with no literal unions, mixed arrays produce a union in order of appearance, and JSON itself has no integer or date type. Those meanings have to be added by hand. The more complete the sample, the closer the generated types sit to the real contract.

In practice the generated interfaces are a draft. Use them to get autocomplete on day one, then tighten fields, add comments and extract shared types as the domain becomes clear. Runtime validation is still required. TypeScript only exists at compile time, so a type assertion will not stop malformed data at the network boundary. A schema library such as zod or valibot defines the shape once. It then derives both the runtime check and the static type.

When to use it

  1. Wiring up a third-party API

    The docs show a sample response but no type definitions. Paste the sample to get interfaces and autocomplete, then check the real response for optional keys. An afternoon of typing turns into a few minutes of review, and the first integration test runs against a type the editor can actually understand.

  2. Migrating an old JavaScript app

    The codebase is full of data.foo.bar with no types. Generate interfaces for the core endpoints, replace any with them, and the compiler points at fields that never existed. The migration scope becomes visible fast. You can then order the work by risk instead of by file count.

  3. Building test fixtures

    Unit tests need mock objects that match the API. Generate the interface first and fill the fixture against it. The editor flags a missing key, the mock stops drifting away from the real response, and a new API field breaks the test before it reaches production.

Tips & tricks

  • Generate from two or three real responses and compare. Optional fields that only appear on some branches show up quickly.
  • After generating, tighten obvious enums into string literal unions. Keeping string lets typos through at compile time.
  • JSON dates arrive as strings. Change them to Date or a documented ISO string type so nobody calls string methods on a timestamp.

Things to watch

  • Treating the output as final

    Fields absent from the sample never appear in the type, and new API fields do not update themselves. Treat the result as a draft, fill gaps from the docs, and regenerate periodically to diff the shape. A short diff review catches renamed fields before they spread through the codebase.

  • Reading a question mark as permission

    An optional marker only means the sample lacked the key. Confirm each one against the business rules and enforce required fields on the server. Otherwise every caller writes null checks while bad data still gets through, and the optional marker quietly becomes a lie.

  • Skipping runtime checks

    A type assertion does not inspect the response. When the API changes shape the code keeps going and fails far from the source. Add a schema check at the boundary so the error surfaces where it started, with the field name right in the message.

Related Tools