U.UtilityApp
⚙️ DevFree · No signup

JSON to TypeScript Converter

Paste JSON, get a TypeScript interface — field types inferred automatically, nested objects included.

What the sample turns into

Paste a JSON object and you get one interface called Root. Strings, numbers and booleans map to string, number and boolean. Nested objects are written inline rather than as separate named interfaces. The built-in sample produces:

interface Root { id: number; name: string; email: string; active: boolean; tags: string[]; address: { city: string; zip: string; }; }

Nested members get the same two-space indent as top-level ones, so deep objects look flat. The code is valid TypeScript, and running your editor's formatter fixes the layout. Keys that aren't valid identifiers are quoted, so first-name becomes "first-name": string;, while $ok stays bare.

Arrays are typed from their first element

The converter looks only at the first item in each array, which leads to three things to check:

  • Mixed arrays: [1, "two", null] becomes number[]. If the data really mixes types, change it to (number | string | null)[].
  • Empty arrays: [] becomes unknown[]. Replace unknown with the real element type, or paste a sample that has at least one item.
  • Arrays of objects: the element type comes from the first object only. Fields that appear in later objects are left out.

If the whole input is an array of records, you get an interface for the first record plus type RootList = Root[];. A bare value such as 42 gives type Root = number;.

Null values and optional fields

A value of null is typed as null, which is almost never what you want. Paste [{"id":1,"nickname":null},{"id":2,"nickname":"Al","admin":true}] and the result has nickname: null; and no admin field at all.

JSON has no way to mark a field as optional, so every key in the sample is required in the output. Before you commit the interface:

  1. Change null types to the real type plus null, such as nickname: string | null;.
  2. Add ? to fields that some responses omit, such as admin?: boolean;.
  3. Rename Root and, if you like, pull nested objects out into named interfaces.

Strings that are really dates, numbers or enums

Types come from JSON values, so "2026-10-19T10:00:00Z" and "19.99" are both just string. That is accurate for the raw response, which is what you parse. If a field only ever holds a few values, such as "active" or "closed", narrow it by hand to a union like "active" | "closed" so the compiler catches typos.

Frequently asked questions

Why do I get an Invalid JSON error?+

The input must be strict JSON. Single-quoted strings, trailing commas, comments and unquoted keys all fail, and the message shows the position where parsing stopped.

Can it generate a type alias instead of an interface?+

For objects it always writes an interface. Change interface Root { … } to type Root = { … }; by hand if your codebase prefers aliases; the members stay the same.

Does the interface check data at runtime?+

No. TypeScript types disappear when the code is compiled, so an API that changes shape will not be caught. Use a runtime validation library if you need that guarantee.

Is it safe to paste production API responses?+

The conversion runs in your browser and nothing is uploaded. If you share the sample JSON with colleagues afterwards, remove personal data from it first.

Embed this tool on your website

Free to use on blogs, school sites and intranets. Paste this code into your page's HTML; please keep the credit line.

<iframe src="https://utilityapp.lat/embed/dev/json-to-typescript" title="JSON to TypeScript Converter" width="100%" height="600" style="border:0;max-width:760px" loading="lazy"></iframe>
<p style="font-size:13px"><a href="https://utilityapp.lat/dev/json-to-typescript">JSON to TypeScript Converter</a> by UtilityApp</p>