Quick answer
To convert JSON to TypeScript, describe each object as an interface whose properties match its keys and value types. Paste a sample into Playxoft's free JSON to TypeScript converter and the interfaces are generated as you type: nested objects become named types, array items are merged so keys missing from some items become optional, and null values are typed T | null. Choose interface or type, readonly and export to match your codebase.
- Interfaces or type aliases
- Optional and nullable detection
- Array samples merged
- Named nested types
- Readonly and export options
- Quoted unsafe keys
- Download types.ts
How to use the JSON to TypeScript
- 1Paste a JSON response into JSON sample, or click Load example.
- 2Set the Root type name, for example
User. - 3Pick interface or type, and how Null values are typed.
- 4Toggle Export, Readonly and Use any to match your codebase.
- 5Copy the code or download types.ts.
How does JSON map to TypeScript types?
Each JSON value has a natural TypeScript counterpart, and the generator applies these rules to every key in your sample:
| JSON value | TypeScript |
|---|---|
"text" | string |
42 or 3.14 | number |
true or false | boolean |
null | adds null to the field's type |
| An object | A named interface |
| An array | T[], with every item merged into one T |
| An empty array | unknown[]: there are no items to learn from |
| An empty object | Record<string, unknown> |
Mixed arrays become unions, so [1, "a"] is typed (string | number)[]. Objects keyed by IDs, such as {"101": {...}, "102": {...}}, become Record<string, T> instead of an interface with one property per ID.
Nested objects are named after their key, and array items get the singular form: an orders array produces an Order interface, categories produces Category. Objects with identical shapes share one type instead of producing duplicates.
Interface or type alias: which should I use?
For object shapes like API responses the two are interchangeable, and the TypeScript handbook suggests using an interface until you need a feature only type aliases have.
| interface | type | |
|---|---|---|
| Extend another shape | extends | Intersection with & |
| Declaration merging | Yes | No |
| Unions and mapped types | No | Yes |
| Error messages | Show the type's name | May expand the full shape |
Pick one and stay consistent. Choose type if your codebase already composes types with unions or utility types such as Pick and Omit, and Readonly if API data should never be mutated after it arrives.
How are optional and nullable fields detected?
A single object can only show what one response looked like. Paste an array of several responses instead and the generator merges them: a key missing from some items becomes optional (?), and a key that is null in any item becomes nullable. These mean different things, and the difference matters:
interface User {
nickname?: string; // the key may be absent
avatarUrl: string | null; // the key is always there; the value may be null
}If your code treats both cases the same way, set Null values to T?. With the exactOptionalPropertyTypes compiler option enabled, an optional property can't be assigned undefined explicitly, so the distinction becomes a compile-time check.
Why should I still validate API responses at runtime?
TypeScript types vanish when your code compiles. If an API returns "price": "12.50" where your interface says number, nothing stops it, and the bug surfaces far from its cause. Types describe what you expect; they don't check it.
For data you don't control, validate at the boundary. A schema library such as Zod checks the data and gives you the static type from the same definition, so the two can't drift apart. The JSON to Zod generator builds that schema from the same sample:
const user = UserSchema.parse(await res.json()); // throws on a mismatchHow are dates, big numbers and unusual keys handled?
- Dates arrive as strings, because JSON has no date type and
JSON.parsedoesn't revive them. ISO 8601 fields are typedstringwith a comment; convert them withnew Date(value)where you use them. - Integers above 2^53 are typed
numberwith a warning comment, becauseJSON.parsehas already rounded them. Ask the API for strings if exact IDs matter. - Keys that aren't identifiers, such as
first nameor2fa, are quoted:"first name": string. Reserved words likeclassanddefaultare fine as property names. - Fields that were only ever null are typed
nullwith a comment, so you remember to widen them once you know the real type. - Empty arrays become
unknown[], orany[]with Use any, since there is nothing to infer from.
Frequently asked questions
Last updated by the Playxoft engineering team.