Developer · Generator
JSON to TypeScript interfaces.
Paste sample JSON and get TypeScript types. A key missing from some array elements becomes optional (?), mixed values become unions, and nested objects get their own interface named from the key. Runs in your browser; nothing is sent anywhere.
Input
Result
Paste JSON and press Generate.
Worked example with null, a mixed array and a missing key
This JSON:
{"id":101,"name":"Ada","email":null,"tags":["admin","dev"],"scores":[9,"n/a",null],"orders":[{"sku":"A1","qty":2},{"sku":"B2","qty":1,"note":"gift","address":{"city":"Toronto"}}]}
becomes:
interface Root {
id: number;
name: string;
email: null;
tags: string[];
scores: (string | number | null)[];
orders: Order[];
}
interface Order {
sku: string;
qty: number;
note?: string;
address?: Address;
}
interface Address {
city: string;
}
Look at what the sample forced. email is only ever null, so it is typed null; a real API probably returns string | null, which a sample cannot reveal. scores holds a number, a string and a null, so the element type is a union. The two orders objects are merged into one Order interface: note and address appear in only one of them, so they are optional.
How the types are inferred
The text is parsed with JSON.parse, which accepts the grammar of RFC 8259, giving six kinds of value: object, array, string, number, boolean and null. Then:
- Primitives map to
string,number,booleanandnull. JSON has one number type, so integers and decimals are bothnumber. - Arrays become
T[], where T is the union of every element type, wrapped in parentheses when it is a union, such as(string | number)[]. An empty array givesunknown[]because nothing shows the element type. - Objects become a named interface (or type alias). Objects found at the same position, for example every element of one array, are merged into one shape. A key present in some but not all of them gets the optional marker
name?: T; types seen for the same key are unioned. - Names come from the key in PascalCase (
user_profilebecomesUserProfile); array items use the singular of the key (ordersgivesOrder). Duplicates get a number suffix. Keys that are not valid identifiers, such asuser-id, are quoted. - Root array or primitive: an interface cannot be an array, so those are written as a type alias.
- readonly: adds
readonlyto every property and usesReadonlyArray<T>.
Limits to know: a sample shows only what it contains. A key present in every sample element may still be optional in production, a field seen only as null has an unknown real type, and a map-like object with arbitrary keys ({"u1": {...}, "u2": {...}}) is better written as Record<string, T> by hand. Review the output before relying on it. This differs from the JSON to JSON Schema Generator, which produces a runtime-validatable schema rather than compile-time types.
Sources (as of 2026-10-01): TypeScript Handbook, Object Types (optional properties, readonly, interfaces); TypeScript Handbook, Everyday Types (arrays, unions, type aliases); RFC 8259, The JSON Data Interchange Format.
Frequently asked questions
Should I use interface or type?
For plain object shapes they behave almost the same. Interfaces can be extended and merged by declaration; type aliases can also name unions and arrays. A root value that is an array is always written as a type alias.
Why is a field typed null only?
Because your sample only had null for it. Add a sample where it has a value, or edit the output to string | null. The tool does not guess.
How do I get optional keys?
Include at least two array elements where one lacks the key. A single object cannot show that a key is optional.
Does this validate data at runtime?
No. TypeScript types are erased at compile time. For runtime checks, generate a schema with the JSON Schema generator.
Inferred from your sample only
The generated types describe the JSON you pasted, not the API or file it came from. Check them against the real contract. Nothing you type is stored or sent anywhere.