How to convert JSON to TypeScript interfaces

Paste a real sample and generate the interfaces, then check the few things a generator can't know from the data: optional fields, nulls, empty arrays and dates.

Published by ThatToolSite

JSON to TypeScript turns sample JSON into interfaces or type aliases, merges every record so optional fields are found, and runs in your browser, so real API responses stay private.

Convert JSON to TypeScript

Generate interfaces from a sample

  1. Get a real response. Copy it from the browser's Network tab, an API client or a log. Real data beats a hand-written example.
  2. Paste it and name the root type. Here the root is called Order. Nested objects get names from their keys.
  3. Pick interface or type, and the options. Export, readonly, and whether fields that are sometimes null should also be optional.
  4. Copy the result into a .ts file. Then fix the few things a generator can't know, below.

For this order:

{
  "orderId": "A-1001",
  "customer": { "name": "Ada", "vip": true },
  "lines": [
    { "sku": "A1", "qty": 2, "price": 4.5 },
    { "sku": "B7", "qty": 1, "price": 12, "discount": 0.1 }
  ],
  "placedAt": "2026-10-01T09:30:00Z",
  "notes": null,
  "1st-choice": "red"
}

the generator gives:

export interface Order {
  orderId: string;
  customer: Customer;
  lines: Line[];
  placedAt: string;
  notes: null;
  "1st-choice": string;
}

export interface Customer {
  name: string;
  vip: boolean;
}

export interface Line {
  sku: string;
  qty: number;
  price: number;
  discount?: number;
}

The array lines got an interface called Line, the singular of the key. Because only the second line has a discount, discount is optional. The key 1st-choice is quoted, since it isn't a valid identifier.

Why one sample isn't enough

A generator can only describe the data it sees. In the order above, notes is typed as null, because that's the only value it ever had. In real use it is probably string | null. Give the generator more than one record, and it merges them:

[
  { "id": 1, "name": "Ada", "email": "ada@example.com", "manager": null },
  { "id": 2, "name": "Linus", "manager": 1, "last-login": "2026-10-01T09:30:00Z" }
]
export type User = UserItem[];

export interface UserItem {
  id: number;
  name: string;
  email?: string;
  manager: number | null;
  "last-login"?: string;
}

Now email and last-login are optional, because one record lacks each, and manager is number | null. Paste a list of records, or several responses wrapped in [ ], to get the same effect.

Nulls, empty arrays, mixed values and dates

In the JSONGenerated typeWhat to do
"notes": nullnullReplace with the real type, such as string | null
"items": []unknown[]Add a sample with items, or write the item type yourself
[1, "two", null](string | number | null)[]Check whether the mix is real or a data bug
"2026-10-01T09:30:00Z"stringJSON has no date type. Convert with new Date() after parsing
12345678901234567890numberJavaScript rounds this. Ask the API for a string

unknown[] is deliberate: it compiles, but TypeScript makes you check an item before using it, unlike any[], which silently allows anything.

interface or type?

For object shapes like these, both work and mean almost the same. The TypeScript handbook's advice is to use interface until you need a feature only type has, such as unions of different shapes. One practical difference: an interface can be reopened and extended by another declaration with the same name, a type alias can't. If your codebase already uses one style, match it; the generator offers both.

Types don't check the data at runtime

JSON.parse returns any. Writing const order: Order = JSON.parse(text) tells the compiler to trust you; nothing checks that the response really has an orderId. If the API changes, the error shows up later, somewhere else.

For data from outside your program, check it once at the edge: a small type guard that tests the fields you rely on, or a schema library such as Zod that validates and gives you the type in one step. The generated interfaces are still useful as the starting point for that schema.

If the sample won't paste because it isn't valid JSON, which is common with JSON copied from AI answers, run it through the JSON validator first.

Sources