All posts
May 24, 20265 min read

Generate TypeScript types from JSON: stop hand-writing interfaces

You have a JSON response from an API and you need TypeScript types for it. Writing those interfaces by hand is slow and error-prone: you miss a field, guess the wrong type, or forget that one property is sometimes null. Generating them from a real sample gets you a correct first draft in seconds, then you refine. Paste a sample into the JSON to TypeScript tool and it produces the interfaces in your browser.

What generation gets right

Given a concrete JSON object, a generator can infer most of the shape mechanically:

  • Primitives map directly: a JSON string becomes string, a number becomes number, a boolean becomes boolean.
  • Nested objects become their own named interfaces, so a user object inside a post produces a User interface referenced from Post.
  • Arrays become T[], with the element type inferred from the items.
  • null values surface as | null so you do not forget to handle them.

This is exactly the tedious, mechanical work you should not be doing by hand. Starting from a real response, rather than the documentation, also catches the gap between what an API claims to return and what it actually returns.

Where a human still has to step in

Generated types describe one sample, not the contract. Two limits to keep in mind:

  • Optional versus always-present. A field missing from your sample is missing from the type. If the API sometimes omits middleName, a single sample will not reveal it. Mark genuinely optional fields with ? yourself, ideally after looking at several responses.
  • Narrow types and unions. A status field that is always "active" in your sample generates as string, but the real contract might be "active" | "archived" | "pending". Tighten these into literal unions by hand; it is where most of the type safety value lives.
  • Numbers that are really enums or IDs. A generator sees number; you may want a branded type or a union.

A clean workflow

  1. Grab a representative response, ideally one with the optional fields populated.
  2. If it is minified or messy, run it through the JSON Formatter first so you can read it.
  3. Generate the interfaces with JSON to TypeScript.
  4. Rename the root interface to something meaningful, mark optional fields, and narrow stringly-typed enums into unions.

Treat the output as a strong first draft, not the final word. If you also need to move that data into a spreadsheet for non-developers, From API to spreadsheet: JSON to CSV covers the other direction, and the JSON to CSV tool handles it.