JSON to TypeScript Converter
Generate TypeScript interfaces or type aliases from a JSON sample, with nested types inferred.
When an API returns JSON, the fastest way to get type safety is to generate TypeScript types from a real response. Hand-writing interfaces for a large payload is tedious and drifts from the actual data. This converter takes a JSON sample and produces TypeScript interfaces or type aliases, with nested objects promoted to named types and arrays typed from their elements.
Paste a JSON sample - for example the response of an endpoint you are about to consume - and press Generate. Every object becomes an interface with the root named after your choice, nested objects become their own named types, and arrays become typed arrays based on their elements. Heterogeneous arrays produce a union type, and empty arrays fall back to unknown[].
Choose between interface and type alias output, and set the root name. The generated code is formatted with two-space indentation and is ready to paste into a .ts file. Everything runs locally, so API samples that may contain personal data never leave your browser.
Features
- Generate interfaces or type aliases from any JSON document.
- Nested objects become named types (Root, RootProfile, RootProfileAddress), readable and composable.
- Arrays typed from their elements; heterogeneous arrays produce union types.
- Primitives inferred: string, number, boolean, null and unknown[] for empty arrays.
- Custom root type name, sanitized to a valid identifier.
- Keys with special characters are quoted in the output.
- Fully offline - the JSON never leaves your browser.
How to Use
- 1
Paste a JSON sample
Enter the JSON you want typed - ideally a representative response with the full shape, not a truncated one.
- 2
Set the root name
Type the name for the root type, for example User or ApiResponse. The default is Root.
- 3
Choose interface or type
Pick Interface for extendable object shapes, or Type alias for unions and primitives. The style applies to every generated type.
- 4
Generate and paste
Press Generate types and copy the output into your project. Nested types are emitted in dependency order.
Example
API response to interfaces
{
"id": 1,
"name": "Ada",
"tags": ["dev", "ml"],
"profile": { "level": 3, "active": true }
}↓
interface Root {
id: number;
name: string;
tags: string[];
profile: RootProfile;
}
interface RootProfile {
level: number;
active: boolean;
}Type alias with a union
{
"sizes": ["s", "m", "l"],
"flags": [1, 2]
}↓
type Root = {
sizes: string[];
flags: number[];
};Common Problems
Typing from a truncated sample
A type generated from partial data is missing fields. Paste the most complete sample you have - the generated types are only as good as the example that produced them.
Optional fields that are not present in the sample
The generator cannot know which fields are optional, because the sample shows values. Fields missing from the sample are absent from the type; fields present are required. Adjust with ? manually where your API varies.
Arrays typed by their first element only
This generator uses all elements when possible and produces a union for mixed arrays. For a reliably uniform array, the union collapses to the single element type.
Special characters in keys
A key like "user-id" is not a valid identifier, so the generator quotes it as "user-id" in the type, which TypeScript accepts. The data shape is preserved exactly.
Deeply nested payloads
Deep nesting produces many named types. Each one is emitted once and reused by reference, so the output stays flat and readable instead of one gigantic inline object.
Treating generated types as a schema contract
Generated types reflect one sample, not the full contract. Pair them with runtime validation to guard against fields that vary across responses.
Name collisions after sanitizing
Two different keys can sanitize to the same identifier, for example "first-name" and "first_name" both becoming FirstName. The generator reuses the first generated type, which keeps the output valid even when source keys are messy.
Technical Details
Every object in the document becomes a named type, named after its path: the root type carries your chosen name, and a nested object under profile becomes RootProfile. Names are sanitized to valid identifiers.
Array element types are computed across all elements. When every element shares one type, the array is typed directly (string[]); when they differ, a union is produced and parenthesized for clarity.
Primitive inference follows JavaScript's typeof rules: string, number, boolean, null. Empty arrays become unknown[] because no element type is available.
Keys are emitted as bare identifiers when valid, and quoted otherwise, matching how you would write the type by hand.
Generation is local and synchronous. The JSON is parsed and analyzed in your browser and never transmitted.
Types are emitted in dependency order: a child type referenced by its parent appears before or after it consistently, so the block is self-contained and paste-ready with no forward-reference errors.
Frequently Asked Questions
Interface or type alias - which should I choose?
Interfaces are extendable and give better error messages in editors, so they suit objects you may grow. Type aliases are needed for primitives and unions. The generator applies your choice consistently to every type it emits.
How are optional fields handled?
A field present in the sample is emitted as required, because the generator cannot infer optionality from one example. Mark genuinely optional fields with ? after generating.
Why is my empty array unknown[]?
Because an empty array gives no evidence of its element type. unknown[] is the honest default - replace it with the real element type once you know what the API returns.
Does it handle nested arrays of objects?
Yes. An array of objects produces a named type for the element and references it as ElementType[]. The same pattern works at any depth.
Is my JSON uploaded?
No. Generation runs entirely in your browser. The JSON is parsed locally and never transmitted, stored or logged.
Can I use the output directly in my project?
Yes, it is valid TypeScript. Paste it into a .ts file and import the types. Note that generated types describe one sample, so keep runtime validation for anything critical.
Why did a nested type get a long name?
Names follow the path - a profile object inside Root becomes RootProfile. Long names are the price of uniqueness, and they make the structure readable at a glance. You can rename them after pasting.
Data & Privacy
Your data stays in your browser. Nothing is uploaded.
- Processing
- Local
- Upload
- None
- Server Storage
- None
- Account
- Not required
Related Tools
JSON Formatter
Format, validate and beautify JSON directly in your browser.
JSON & Data
JSON Validator
Validate JSON and pinpoint the first error with a line, column and plain-English explanation.
JSON & Data
JSON Minifier
Compress formatted JSON into a single compact line and see exactly how many bytes you save.
JSON & Data
JSON Diff
Compare two JSON documents and see every added, removed or changed value with its exact path.
JSON & Data
JSON to CSV Converter
Convert a JSON array of objects into a CSV file with automatic headers and proper escaping.
JSON & Data
CSV to JSON Converter
Convert CSV files into a clean JSON array, with optional automatic type detection.
JSON & Data