JSON to TypeScript Interfaces

Paste a JSON sample from an API response or a settings file. The tool writes TypeScript interfaces that describe it, with a name for each nested object. Nothing you paste leaves your browser.

Free Runs in your browser Checked Tuesday, November 10, 2026

A typical JSON object or array. Several array items are merged into one interface.

A plain name such as Root, Product or ApiResponse.

Tick it when the types are imported in another file.

Result

TypeScript interfaces — Copy the code, or download it as types.ts.
Declarations — The interfaces and type aliases in the code.
TypeScript interfaces

This tool runs in your browser. What you enter is not sent to us.

How to use it

  1. Paste a typical JSON value into JSON sample. The types appear as you type.
  2. Type a name under Root interface name for the outermost object, such as Product.
  3. Untick Write export before each declaration if the types stay in the same file.
  4. Copy the TypeScript interfaces, or download them as types.ts.

How the types are worked out

Each JSON object becomes an interface. Its name comes from the key that holds it, in PascalCase: the key first-name gives FirstName. The items of an array take the singular of the array's key, so items gives Item. When a name is already taken, the parent's name is put in front of it.

Strings, numbers and booleans become string, number and boolean. null is written as null in a union, such as number | null. An array of values becomes a type followed by []; an empty array becomes unknown[] because the sample does not say what it holds.

key "first-name" -> property "first-name": string;   items -> Item[]

Several samples in one array

A list of objects is read as one shape. A key that appears in every item is required; a key missing from some items is written with a question mark, as optional. A key that holds different types in different items becomes a union, with string first, then number, boolean, the interface, the array and null.

A sample shows only the values it contains. A key that a real API sometimes leaves out may be missing from a single example, so add a second item with it if you need the type to show it as optional.

Worked example: the default sample

The default sample is one object with five keys. Its owner key holds an object, so the code has an Owner interface. Its items key is an array of two objects, so the code has an Item interface. The sku and price keys are present in both items and are required; the discount key is null in one item and a number in the other, so it is number | null; the note key appears in one item only and is optional.

The result has three declarations: Root, Owner and Item, and the count shows 3.

Frequently asked questions

Why is a field marked with a question mark?

The field is missing from at least one object of the sample. Such a field may be absent in the real data, so TypeScript treats it as optional, and code that reads it must check it first.

Why does my field show a union such as string | number?

Different items hold different types for that key. The type lists every type seen in the sample, so the code must check which one it has before using the value.

Does the tool check my real API data?

No. It writes the types of the sample you paste. A sample with one item cannot show a field that appears only later, so use a typical response with several items when you can.

Why are some property names written in quotes?

A name that is not a plain identifier, such as first-name or 2fa, must be quoted in TypeScript. Names that are valid identifiers are written without quotes.

Can I use the output with JavaScript?

The interfaces are TypeScript only. They are removed when the code is compiled, so a JavaScript project needs the JSON to be checked another way, or a TypeScript build step.

Sources

Figures and text last checked on Tuesday, November 10, 2026.

We use necessary cookies to run the site. With your consent, Google also uses advertising cookies to show personalised ads. If you reject them, you still see ads, but they are not personalised.