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:
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]becomesnumber[]. If the data really mixes types, change it to(number | string | null)[]. - Empty arrays:
[]becomesunknown[]. Replaceunknownwith 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:
- Change
nulltypes to the real type plus null, such asnickname: string | null;. - Add
?to fields that some responses omit, such asadmin?: boolean;. - Rename
Rootand, 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>