Already have a JSON Schema contract? Use JSON Schema to TypeScript to generate declarations from required fields, enums and references instead of inferring them from sample values.
Why generate TypeScript types from JSON?
Writing interfaces for a large API response by hand is slow and error-prone. It's easy to miss a nested field or
a property that is sometimes absent. Generating them from a real response gives you an accurate starting point in
seconds. Then you can rename types, tighten string to literal unions, or add comments.
Example
{
"id": 7,
"title": "Ship v2",
"assignee": {
"id": 3,
"name": "Grace"
},
"labels": [
"backend",
"urgent"
],
"comments": [
{
"author": "Grace",
"body": "On it",
"editedAt": null
},
{
"author": "Linus",
"body": "LGTM"
}
]
}
export interface Issue {
id: number;
title: string;
assignee: Assignee;
labels: string[];
comments: Comment[];
}
export interface Assignee {
id: number;
name: string;
}
export interface Comment {
author: string;
body: string;
editedAt?: null;
}
Notice how the generator:
- created a separate
Assigneeinterface for the nested object; -
named the array item type
Commentby singularizingcomments; -
marked
editedAtas optional because only one of the two comments had it; - typed
labelsasstring[].
How type inference works
| JSON value | TypeScript type |
|---|---|
"text" | string |
42, 3.14 | number |
true | boolean |
null | null (or T | null when mixed) |
{ ... } | A named interface |
[1, 2] | number[] |
[1, "a"] | (number | string)[] |
[] | unknown[] (no items to infer from) |
Keys that aren't valid identifiers, like first-name, are quoted automatically. Objects with an
identical structure share one interface instead of being duplicated.
Tips for better results
- Use real data with variety. Include array items that show optional fields and nulls, so the generator can see them.
-
Review string fields. A
status: "open"field is inferred asstring. Narrow it to"open" | "closed"if you know the possible values. -
Dates are strings in JSON. Keep them as
stringin the type, and convert them toDateat the edges of your app. - Validate at runtime. Types don't check data coming from the network. Pair them with a Zod schema.
Need a repeatable test payload? Build one with Mock Data Generator. For a backend model, choose JSON to Rust or JSON to PHP and review each target language’s number and optional-field rules.
Frequently asked questions
How do I convert JSON to a TypeScript interface?
Paste a JSON sample into the tool above. It generates an interface for the root object and one for every nested object, names them from their keys, and infers arrays, unions and optional properties. Copy the output into a .ts file.
How are optional properties detected?
When an array contains several objects, the tool merges them. A key that appears in only some of the objects becomes optional (key?: type). To get accurate optional fields, paste a sample with several representative items.
Should I use interface or type?
For plain object shapes both work the same. Interfaces can be extended and merged, and they give slightly clearer error messages. Type aliases are needed for unions and mapped types. Many teams default to interfaces for API models. Use the toggle to switch.
What happens with null values?
A value that is always null is typed as null. If the same key is null in some samples and a string in others, it becomes string | null. Paste more samples for more precise types.
Can I get runtime validation too?
TypeScript types are erased at runtime and don’t validate API responses. Use the JSON to Zod tool to generate a schema that validates data at runtime and infers the same TypeScript type.