Data Transformation intermediate 12 min

Generate Types From a Real API Response

Create TypeScript interfaces from actual JSON so client code starts from the real shape.

Scenario

A new endpoint is stable enough to integrate against, and the frontend needs TypeScript types for its response. Writing interfaces by hand from a JSON example invites the classic drift bugs: a typoed field name that compiles fine and fails at runtime, or a field typed string that is sometimes null. Generating the interface from a real response gets the mechanical part right so review time goes to the judgment calls.

Broken input

{"id":"user_123","email":"ada@example.test","roles":["admin"],"profile":{"timezone":"UTC"}}

Goal

Use JSON to TypeScript Interface Generator to derive interfaces from the response sample, then review them as a draft — the generator captures what this response looks like, and you decide what every response is allowed to look like.

Tool sequence

  1. Open JSON to TypeScript Interface Generator.
  2. Paste a real captured response, not a hand-typed reconstruction — the whole point is to type what the API actually returns.
  3. Generate and read the result: primitives typed from values, roles inferred as string[], and the nested profile object extracted into its own interface.
  4. Rename the generated interfaces to domain names (User, UserProfile) and mark fields optional or nullable where the API contract says so — one sample cannot tell you that.
  5. If several teams consume the endpoint, also generate a schema with JSON Schema Validator / Generator so the contract is enforceable outside TypeScript.

Checkpoint output

interface User {
  id: string;
  email: string;
  roles: string[];
  profile: Profile;
}

interface Profile {
  timezone: string;
}

The generated types carry the string fields, the roles: string[] array, and a nested profile interface — a correct skeleton awaiting optionality decisions.

Common mistakes

  • Generating types from invalid or truncated JSON and typing a shape the API never returns.
  • Treating one example as proof that every field is always present — samples cannot show optionality.
  • Skipping the rename pass, so RootObject and Profile2 leak into the codebase.
  • Regenerating types after an API change without diffing, silently overwriting hand-added | null annotations.

Related tools and lessons