Skip to content

JSON to TypeScript — generate interfaces from a payload

Free · no sign-up · runs in your browser

Paste a JSON payload and get TypeScript interfaces: merged array shapes, optional properties, and real unions instead of any. Runs in your browser — nothing is uploaded.

Paste a whole response — more elements means more accurate optionals.

TypeScript

export interface Root {
  id: number
  name: string
  active: boolean
  tags: string[]
  owner: Owner
  members: Member[]
}

export interface Owner {
  id: number
  email: null
}

export interface Member {
  id: number
  email: string | null
  profile?: Profile
}

export interface Profile {
  avatar: string
}

Converted in this page. Nothing is uploaded — check your network tab.

Paste an API response and get the interfaces for it. The useful part is what happens with arrays: every element is merged into one type, so a key missing from some of them becomes optional and a key that is a string in one and null in another becomes a union — which is the fact the payload is telling you, and the whole reason to generate types rather than write them. Everything runs in this tab, so you can do this with a real response containing real data.

How it works

  1. 01Paste a JSON payload. A whole API response works better than a trimmed one — the more elements an array has, the more accurate the optional properties and unions.
  2. 02Name the root type. It is pascal-cased for you, so "api response" becomes ApiResponse.
  3. 03Choose interfaces or type aliases. Interfaces are the common choice for object shapes; type aliases compose more easily and are what you want if you will union them later.
  4. 04Turn on readonly to mark every property readonly, which is usually right for data you fetched and should not mutate.
  5. 05Nested objects become their own named interfaces rather than inline shapes, so you can import and reuse them. Names come from the key, and a collision takes a numeric suffix.
  6. 06Copy the declarations into your project. They are plain TypeScript with no dependencies.

Use cases

  • Typing a third-party API that ships no types and no OpenAPI spec.
  • Turning a captured response into a starting point instead of writing thirty properties by hand.
  • Finding out which fields are actually optional, by pasting a list response and reading the question marks.
  • Spotting the fields that are sometimes null — the ones that cause runtime errors months later.
  • Generating types from a payload containing real customer data, without sending it to a third-party service.
  • Checking that a payload matches the shape you assumed before you write the code that consumes it.

Frequently asked questions

How are arrays handled?

Every element is merged into a single interface rather than producing one type per element. A key present in some elements and missing from others becomes optional; a key with different types across elements becomes a union. So [{"a":1},{"a":2,"b":"x"}] yields one interface with a: number and b?: string. This is the main thing that separates a useful converter from typeof — and the reason to paste a whole list response rather than a single record.

Why is a field typed string | null instead of just string?

Because it was null somewhere in the payload you pasted. That is the tool reporting the shape of your data rather than the shape you hoped for, and it is usually the most valuable line in the output — a nullable field that gets typed as non-null is exactly the bug that shows up in production months later. If the null was a fluke of that one response, delete the union by hand.

Can it infer types the JSON does not contain?

No, and it does not pretend to. JSON has no date type, so an ISO timestamp is a string; it has no integer type, so 1 and 1.5 are both number; and an empty array is unknown[] because there is nothing in it to infer from. Guessing Date from a string that looks like one is how converters produce types that do not match what JSON.parse actually returns.

Is my payload sent anywhere?

No. It is parsed and converted in this page, with no request to any server — check your browser's network tab, or disconnect after the page loads. This matters more here than for most tools, because the payloads worth typing are real API responses, often with real data in them, and pasting those into a hosted converter means handing them to someone else.

What happens to keys that are not valid identifiers?

They are quoted rather than renamed: content-type stays "content-type", not contentType. The key is a fact about the wire format, and silently renaming it would produce a type that does not describe the payload — your code would compile and then read undefined. Type names are a different matter: those are generated, so a key like weird key becomes the type WeirdKey.

Should I use interfaces or type aliases?

For plain object shapes they are almost interchangeable. Interfaces support declaration merging and give slightly better error messages on object types; type aliases can express things interfaces cannot, such as unions and mapped types, and compose more predictably. If you have no reason to prefer one, take interfaces — and switch to type if you plan to union these with anything.

Related resources

Related reading

More tools