What This Tool Does
This tool inspects one sample JSON value and infers matching TypeScript interface declarations from it. The outermost object is always named Root. For every nested object it encounters, it generates a separate, named interface rather than inlining the shape — the name is built from the immediate parent interface's name plus the title-cased property key. So a Root object with an address key produces a standalone RootAddress interface, and if that address object itself had a nested geo key, that would become RootAddressGeo, and so on down the tree.
Arrays are typed from their first element only: an array of strings becomes string[], an array of objects becomes SomeName[] with SomeName generated as its own interface, and an empty array — since there's nothing to inspect — becomes unknown[]. Primitive values map to JavaScript's own typeof result (string, number, boolean), and null is emitted as the literal type null. When the output contains multiple interfaces, Root is always printed first, followed by the nested interfaces in the order they were discovered.
How to Use It
- Paste a representative sample of your JSON — an API response body, a config object, or a saved payload — into the Input box.
- Click Run.
- The generated
Rootinterface, followed by any nested interfaces it references, appears in the Output box. - Copy the interfaces into your
.tsfile, and renameRootto something meaningful for your codebase (e.g.User,OrderResponse). - Review the output for optional fields, nullability, and array item variation before treating it as final — see Limitations below.
Worked Example
Input:
{
"id": 1,
"name": "Ada",
"address": { "city": "Berlin" },
"tags": ["a", "b"]
}
Output:
interface Root {
id: number;
name: string;
address: RootAddress;
tags: string[];
}
interface RootAddress {
city: string;
}
Notice the naming: because address is a key on Root, its generated interface is named RootAddress — the parent interface's name followed by the title-cased key. The tags array is typed from its first element ("a", a string), producing string[] rather than a separate interface, since string arrays don't need one.
Common Use Cases
- Typing an API response quickly — paste a real response body and get a starting interface instead of typing every field by hand.
- Scaffolding types from a sample payload — turn a saved test fixture or webhook payload into TypeScript types for a new integration.
- Documenting expected shapes for a team — share a generated interface in a PR or ticket so reviewers can see the exact structure being consumed.
- Bootstrapping a data model — use the generated interfaces as a first draft before refining them into your project's shared type definitions.
Limitations
This tool infers types from a single example value — it has no visibility into any other possible response your API or data source might produce. Be aware of the following before using generated output in production:
- No optional fields. Every key present in the sample is generated as required. If a field is sometimes absent, you must add
?by hand. - No unions across array items. Array typing only looks at the first element. If your array actually mixes shapes or types (e.g. some items have an extra field, or a numeric ID sometimes arrives as a string), that variation is silently missed.
- No real nullability. A
nullsample value produces the literal typenull, not a union likestring | null. If the field can hold both a string and null, you need to add that union manually. - One sample, one shape. If your data source returns different shapes under different conditions (error vs. success responses, different API versions), generate and merge interfaces from each variant separately.
Treat the output as a strong first draft, not a final type definition — always review it against your actual API documentation or several sample payloads.
FAQ
Does it detect optional properties?
No. Only the fields present in the JSON you paste in are considered, so all generated properties are required. Add ? manually for fields that can be missing.
What happens with an empty array?
It's typed as unknown[], since there's no first element to infer a type from. Replace unknown once you know what the array will actually hold.
How are nested interfaces named?
Using the pattern <ParentInterfaceName><TitleCaseKey>. The outermost object is always Root, so a nested address object becomes RootAddress, and nesting further down chains the same way (e.g. RootAddressGeo).
Does it handle null values correctly?
Not fully. A null sample value is typed as the literal null rather than a union such as string | null. Widen these types by hand based on what the field can actually contain.
Is my data uploaded anywhere?
No. Generation happens entirely client-side in your browser — nothing is sent to a server or stored.