About this tool
JSON to TypeScript reads an example of your data, such as an API response, a config file or an export from a database, and writes the types that describe it. Choose interfaces, type aliases or a Zod schema, and the code updates on every keystroke, ready to copy into your project or download as a .ts file.
Most converters look only at the first item of a list and name every nested type after its parent with a number on the end. This one reads every item, so a key that appears in only some records becomes optional and a value that is sometimes null becomes “| null”. Nested objects are named after their keys: “shippingAddress” becomes ShippingAddress, and a list called “items” holds Item, not Items. Two objects with exactly the same fields can share one type, odd keys such as “first-name” are quoted, and mixed lists turn into unions like (string | number)[].
The conversion happens on your device. The JSON is never uploaded, which matters when the sample is a real customer record or a production config. If what you paste isn’t valid JSON, the tool tells you the line and column of the first mistake in plain words, and it quietly copes with JavaScript-style objects that have comments, trailing commas or single quotes.
How to use JSON to TypeScript
- Paste your JSON into “Your JSON”, press “Open file” to load a .json file, or drop one on the box. “Example” loads a sample order.
- Pick the output: “Interfaces”, “Type aliases” or “Zod schema”.
- Type a “Root type name”, for example Order or User. Nested types are named for you.
- Tick the options you want, such as optional keys, readonly, date strings or example values as comments. The code updates straight away.
- Press “Copy”, or “Download .ts” to save the file.
A list of two users, {"id": 1, "nick": null} and {"id": 2, "nick": "z", "email": "a@b.c"}, with the root name “users” gives: type Users = User[], and interface User { id: number; nick: string | null; email?: string; }.
Features
- Three outputs: TypeScript interfaces, type aliases, or a Zod schema with a matching z.infer type for each object.
- Every list item is merged, so keys missing from some items become optional (you can turn this off).
- Nulls become “| null” in TypeScript and .nullable() in Zod; whole numbers become .int() in Zod.
- Readable names from keys: PascalCase, singular for list items (categories → Category, people → Person), clashes resolved with the parent’s name.
- Identical shapes reuse one type, and names that would hide built-in types (String, Date, Map) get “Type” added.
- Options for export, readonly properties and arrays, quoting every key, indent with 2 or 4 spaces or tabs, and example values as comments.
- Optional date detection: ISO dates get a note in TypeScript and z.string().datetime() or .date() in Zod.
- Plain-English errors with the line, column and a pointer, and lenient reading of JavaScript-style objects.
Tips and good to know
- Give it several records, not just one. The more items in a list, the better it can tell which keys are really optional.
- A key that is null in every sample can only be typed as null. Add one record where it has a real value to get string | null.
- Generated types describe the sample, not every possible response. Check optional keys and unions against your API’s documentation.
- With Zod, the schema validates data at runtime and z.infer gives you the static type, so you only maintain one definition.
- Dates in JSON are always strings. The date option documents and validates them; convert them to Date objects yourself after parsing.
Frequently asked questions
Is my JSON uploaded anywhere?
No. The types are generated in your browser, in a background worker on this page. Your JSON is never sent to AroraTools or anyone else. Only your option choices are remembered on this device.
Is it free, and is there a size limit?
It is free with no sign-up. Files up to 25 MB open directly and pasted text has no fixed limit, though very large samples are slower on older phones. A few representative records usually describe the shape just as well.
Does it work on a phone or offline?
Yes. It works in Safari, Chrome and Firefox on phones, tablets and computers, and once the page is open it keeps working without a connection.
Should I use interfaces or type aliases?
For plain object shapes they behave almost the same. Interfaces can be extended and merged, and many style guides prefer them for objects; type aliases can also name unions and lists. Pick whichever your project already uses.
Which Zod version does the schema need?
It uses z.object, z.array, z.union, .optional(), .nullable() and .int(), which work in Zod 3 and Zod 4. The date checks, z.string().datetime() and .date(), need Zod 3.23 or later; they still work in Zod 4.
Why is a field typed as unknown?
An empty list [] gives no clue about what it holds, so its items are unknown. Mixed lists also become unknown[] if you turn off “Mixed lists as unions”. Add a sample with real items and the type fills in.
Page last reviewed