JSON to TypeScript Interface — Auto-Generate Types from Any JSON
Paste JSON and get TypeScript interfaces instantly. Auto-generates nested types, optional fields, and union types. No manual typing — copy and paste into your project.
You just got access to a third-party REST API. The docs show a sample response — 20 fields, three nested objects, a few arrays. Now you need TypeScript interfaces so your IDE can autocomplete and your compiler can catch mismatches. You open a new file and start typing.
Twenty minutes later you have a pile of interfaces, some of them probably wrong. Is userId a number or a string? Is metadata always present or sometimes undefined? Did you spell renewsAt right? And that array of mixed objects — you just gave up and typed any[].
This is the manual path. There is a faster one.
Use the JSON to Code generator to paste your JSON and get TypeScript interfaces in seconds. No typing, no guessing, no missed fields.
What a JSON-to-TypeScript generator actually does
A generator reads your JSON structure and walks every key and value. For each value it infers the TypeScript type: 42 becomes number, "alice" becomes string, true becomes boolean, null becomes null, an object becomes a new interface, an array becomes T[]. When it encounters nested objects, it creates a named interface for each one and references it from the parent.
The output is structurally complete. Every key in your sample JSON is represented. Every nested object becomes its own interface. Arrays of objects produce a typed array reference. You get something you can drop straight into a types/ folder and start using.
A complete example
Take a typical user response from an API:
{
"id": 42,
"username": "alice",
"email": "alice@example.com",
"subscription": {
"plan": "pro",
"renewsAt": "2026-12-01",
"features": ["api", "export", "sso"]
},
"lastLogin": null
}
A JSON-to-TypeScript generator produces:
interface Subscription {
plan: string;
renewsAt: string;
features: string[];
}
interface User {
id: number;
username: string;
email: string;
subscription: Subscription;
lastLogin: null;
}
Notice a few things. The generator correctly identified id as number, not string. The nested subscription object became its own Subscription interface, referenced from User. The features array of strings became string[]. And lastLogin, which was null in the sample, became the type null — we will come back to that.
Handling the tricky cases
Generators get most cases right, but real API responses throw a few curveballs.
Null values
When a field is null in your sample JSON, the generator can only type it as null — it has no way to know what the field would contain when populated. In practice, lastLogin: null means the user has never logged in. The real type is string | null (an ISO timestamp or null). After generation, fix these manually:
lastLogin: string | null;
This is the most common post-generation edit. Any field that could be a real value or null needs the union type.
Optional fields
A sample API response might not include every field. If your user object sometimes omits profilePicture and sometimes includes it, the generated interface will reflect only what was in your sample. Always review generated interfaces against the API documentation and mark optional fields with ?:
interface User {
id: number;
username: string;
profilePicture?: string; // not always present
}
A missing ? compiles fine but breaks at runtime when the field isn’t there.
Mixed-type arrays
If an array contains a mix of types — say [1, "two", 3] — the generator produces a union: (number | string)[]. This is correct TypeScript. If the array is empty [], the generator cannot infer element type and outputs unknown[]. Replace it with the correct element type once you know what the array holds.
Deeply nested structures
A four-level-deep JSON object produces four named interfaces. The naming convention matters: generators typically name them based on the key (so subscription → Subscription). For ambiguous keys like data or result, rename the generated interfaces to something meaningful before checking them in.
Making generated interfaces production-ready
Raw generator output is a starting point. Before committing to types/api.ts, make these adjustments:
Export everything. Generators usually output un-exported interfaces. Add export to every interface that will be used outside the file:
export interface Subscription {
plan: string;
renewsAt: string;
features: string[];
}
export interface User {
id: number;
username: string;
email: string;
subscription: Subscription;
lastLogin: string | null;
}
Use readonly for API response fields. If you never mutate data coming from the API, mark fields readonly to prevent accidental writes:
export interface User {
readonly id: number;
readonly username: string;
readonly email: string;
}
Fix null → proper union types. As noted above, walk every null field and decide if it should be T | null or T | null | undefined.
Consider type over interface for union scenarios. When you need a type that is one of several string literals — like a status field — use a type alias instead:
export type PlanType = 'free' | 'pro' | 'enterprise';
export interface Subscription {
plan: PlanType; // not just string
renewsAt: string;
features: string[];
}
Narrowing plan from string to a union literal type catches invalid plan values at compile time rather than at runtime.
interface vs type — knowing when to use which
TypeScript gives you two ways to describe object shapes: interface and type. For most API response shapes, interface is the right choice. It’s extendable (you can extends it), it produces better error messages, and it’s slightly faster for the TypeScript compiler to process large codebases.
Use type when:
- You need a union type at the top level:
type Result = Success | Error - You need a tuple:
type Pair = [string, number] - You need to map or intersect types:
type ReadonlyUser = Readonly<User>
For the generated Subscription and User shapes above, interface is appropriate.
The actual workflow for API integration
Here is the end-to-end workflow developers use:
-
Get a real sample response. Hit the endpoint in Postman, your browser devtools, or with
curl. Make sure the sample represents a full response — not an empty one. -
Validate and format the JSON first. Use the JSON Formatter to make sure the JSON is well-formed. A missing comma or unbalanced brace causes the generator to fail with a parse error that can be confusing to track down.
-
Generate the interfaces. Paste the formatted JSON into the JSON to Code generator. Review the output — check field names, look for
nulltypes that need unions, verify nested interface names make sense. -
Edit post-generation. Add
export, fix nullables, add optionals with?, narrow string fields to literal union types where appropriate. -
Save to
types/api.ts. Keep all API response interfaces in one file or atypes/api/directory. This makes them easy to find and update when the API changes. -
Re-generate when the API changes. When a new field is added or a type changes, paste the new sample response and diff the output against your existing interfaces.
The total time for a 20-field API response goes from 20 minutes of manual typing to under 5 minutes — most of which is reviewing and editing the output.
What generators cannot do for you
Generators work from a single sample. They cannot:
- Know that a field is sometimes a string and sometimes a number across different responses
- Detect that a field is deprecated
- Add JSDoc comments explaining what each field means
- Know that
priceshould benumberbut treated as cents and displayed divided by 100
These require human judgment. The generator handles the mechanical part — you handle the semantic part. That split is a good use of both.
Written by Mian Ali Khalid. Last updated 2026-05-12.
Related posts
- JSON to C# Classes — Generate .NET Model Classes Instantly — Paste JSON and get C# classes with properties, data annotations, and Newtonsoft …
- JSON to Go Struct — Generate Golang Types from a JSON Sample — Paste JSON and get Go struct definitions with json tags. Handles nested structs,…
- JSON Formatter — Why Formatting JSON Matters and How It Works — A JSON formatter takes compact, hard-to-read JSON and adds whitespace and indent…
Written by Mian Ali Khalid. Part of the Data & Format pillar.