TypeScript interfaces · type-safe · client-side

Generate TypeScript interfaces from JSON

Paste any JSON sample and get strongly-typed interfaces with nested types, arrays, and optional fields inferred automatically.

JSON → TypeScript Workspace
Input size
240 B
12 lines
Output size
298 B
3 interfaces
Root name
Root
export interface
Status
Valid
TypeScript
Root name
input · json sample
output · typescript
export interface RootUserAddress {
  city: string;
  country: string;
}

export interface RootUser {
  id: number;
  name: string;
  email: string;
  active: boolean;
  roles: string[];
  address: RootUserAddress;
  lastLogin: null;
}

export interface Root {
  user: RootUser;
  version: number;
}
Step-by-step Tutorial

How to generate TypeScript interfaces from JSON

Stop typing types by hand. Paste a real JSON sample — an API response, config object, or analytics event — and get an export interface tree ready to paste into your project. Strings, numbers, booleans, nulls, arrays, and nested objects all map to their idiomatic TypeScript equivalent.

  1. 01

    Paste a representative JSON sample

    TypeScript is a structural type system, so its interfaces describe shape, not identity. The generator reads the shape you provide — the richer the sample, the more precise the resulting export interface tree.

    Both pretty-printed and minified JSON work. Drop in API responses, OpenAPI examples, Stripe / GitHub / Slack webhook payloads, exported analytics events, or any other production sample.

    If a field is sometimes null, include a sample where it is — the inference can only see what you give it.

    API responseOpenAPI examplewebhook payloadanalytics eventstructural typing
    input · json sample2 keys
    {
      "user": {
        "name": "Ada",
        "age": 30
      }
    }
    52 B · 6 linesvalid · loaded
  2. 02

    Pick a root interface name

    Defaults to Root. Change to something domain-specific — User, ApiResponse, WebhookPayload. Nested objects automatically get prefixed PascalCase names like RootUser, RootUserAddress, so you can reference each sub-shape independently.

    Property keys that aren't valid JS identifiers (kebab-case, leading digits, embedded spaces, reserved words) are quoted automatically per the TypeScript grammar.

    Need camelCase / snake_case conversion? Pair with Case Converter before generating.

    export interfacePascalCasenested typesreserved wordsidentifier-safe
    naming · root → UserPascalCase
    export interface User {
      name: string;
      age: number;
    }
    55 B · 4 lines · 1 rootcompiles · ready
  3. 03

    Review the inferred types and narrow unions

    The generator maps JSON values structurally: strings → string, integers and floats → number, booleans → boolean, arrays → T[] (item type from the first element), nested objects → named child interfaces.

    null becomes the literal type null; empty arrays default to unknown[]. For fields that flip between shapes in production, hand-edit to a union (string | null) and use a type guard or in-operator narrowing where you read it.

    Sometimes-missing fields aren't inferred from a single sample — mark them optional with ?: so consumers handle absence safely.

    stringnumberT[]union narrowingoptional ?
    output · interfaces.ts · 2 types
    interface Root {
      user: RootUser;
    }
    interface RootUser {
      name: string;
      age: number;
    }
    78 B · 6 linestype-safe · strict
  4. 04

    Copy or download as .ts

    One click copies the generated interfaces to your clipboard, or download as types.ts / types.d.ts for your project. No runtime imports required — the output is pure declaration code that disappears at compile time.

    For runtime validation alongside compile-time types, pair with JSON to Zod (z.infer mirrors these interfaces exactly). For the Python equivalent, use JSON to Pydantic.

    Everything runs locally — open DevTools → Network to confirm zero outbound requests.

    clipboardtypes.ts.d.tsno runtime costprivacy-first
    export3 actions
    ✓ Copied to clipboard
    ✓ Saved: types.ts
    ✓ 0 outbound requests
    ✓ 100% client-side
    ready to shiptsc-clean · success
Pro tips

Production-grade type inference tips

Pick a representative sample

The generator only sees the shape you give it. If a field can be null in production, include an example where it's null so you get the proper type.

Add | null manually

For fields that are sometimes null, edit the output to add | null unions. The auto-inference can't see what's not in your sample.

Mixed-type arrays

If an array contains mixed types, the generator picks the first element's type. Edit to (A | B)[] manually.

Optional fields

Mark not-always-present keys with ?: so consumers handle absence. Easy refactor after the codegen.

Pair with runtime validation

TypeScript types disappear at runtime. Pair with Zod or io-ts for parse-time validation.

Big-integer precision

JavaScript loses precision past 2^53−1. Stringify large IDs in your source JSON; types will read string.

Use Cases

When to auto-generate TypeScript types

Anywhere you'd otherwise hand-type interfaces. Saves time, avoids typos, and stays in sync with reality.

REST & GraphQL clients

Generate types from a real response sample, then write your fetch wrapper with full IntelliSense. Output round-trips losslessly through JSON.parse + JSON.stringify, so the file you save is byte-identical to what you see. Streaming parsers, jq pipelines, and Postgres jsonb columns all accept the result without complaint.

fewer any types

Config files & manifests

Type your tsconfig.json, theme tokens, or feature-flag schemas to catch typos at compile time.

compile-time safety

Webhook payloads

Paste a real webhook body from Stripe, Slack, GitHub, or Shopify and get a typed handler signature. Handles emoji and non-ASCII via UTF-8 throughout — your data survives copy-paste between editors, terminals, and IDEs. Combining marks and ZWJ sequences come out the other side intact.

fewer untyped handlers

CMS / headless content

Generate types from a Contentful, Strapi, or Sanity response so your editors see real autocomplete. Re-parses on every keystroke so syntax errors are caught at the exact character. Strict RFC 8259 — no trailing commas, no comments, no unquoted keys — keeps downstream parsers happy.

round-trip safe

Local storage / IndexedDB

Type structured client-side data so reads and writes stay aligned across releases. Streams large documents without a server round-trip — privacy stays in the tab. Heavy parsing runs through useMemo so even 5 MB payloads keep the editor responsive.

schema drift caught

Analytics events

Snapshot a real event payload, type it, then your tracking library validates at compile time. Output is byte-stable: same input plus same options always produces identical bytes, ideal for content-addressed caches and snapshot tests. Downloads ship with the application/json MIME so editors apply syntax highlighting.

tracking discipline
FAQ

Frequently asked questions

Quick answers about JSON → TypeScript inference.

Yes. Each nested object becomes a separately-named export interface so you can reference it elsewhere.
Null becomes the literal type null. If a field can be both T and null in production, edit the output to T | null — the inference can't see what's missing from your sample.
Yes. The first element's type becomes the array's item type. For mixed arrays, edit to (A | B)[] manually.
The generator marks every field as required because it can't infer absence from a single sample. Add ?: by hand for genuinely optional keys.
No. Parsing and codegen run locally. Open DevTools → Network to confirm zero outbound requests.
Suggest a tool

Something missing?

Tell us what you need. We ship the top requests every two weeks.

Sent straight to the maintainers · no account needed
47 in queue·8 shipped this month
Request queued. Thanks!