JSON to TypeScript
Paste JSON and the tool writes the types: the sample customer becomes 3 interfaces (Customer, Address, Order), with note?: string optional because only one of the two orders has it and email: null kept as null. Switch the output to Zod or Pydantic for the same shape.
How to use
- Paste your JSON into the input box, or press Sample to see an example.
- Type a root name such as User or ApiResponse. Pick TypeScript, Zod or Pydantic, and for TypeScript choose interface or type.
- Copy the result. It updates as you type, and invalid JSON shows the line and column of the error.
How it works
The tool reads the whole document and builds one merged shape. Each nested object becomes its own named type, named after its key in PascalCase (shipping_address becomes ShippingAddress). Items of an array are named from the singular of the key (orders becomes Order).
Array items are merged. If every object has a key it is required, and if some objects lack it the key becomes optional (key?: type). If items have different value types the type is a union, such as string | number.
null is kept as a type: a key that is null in one object and a string in another becomes string | null. An empty array becomes unknown[] and an empty object becomes Record<string, unknown>, because there is nothing to infer from.
Keys that are not valid identifiers, such as first-name, are quoted in TypeScript and Zod. In Pydantic they get a safe field name with the original as an alias. Two different shapes with the same name get a number (Item, Item2).
How JSON types map
| JSON value | TypeScript | Zod | Pydantic |
|---|---|---|---|
| "text" | string | z.string() | str |
| 1 or 1.5 | number | z.number() | int if every value is whole, otherwise float |
| true | boolean | z.boolean() | bool |
| null | null | .nullable() | Optional[...] |
| [ ... ] | T[] | z.array(...) | list[T] |
| { ... } | interface | z.object({ ... }) | class (BaseModel) |
| key missing in some objects | key?: T | .optional() | Optional[T] = None |
What a sample cannot tell you
- A key that is always present in your sample may still be optional in the API. Add more sample objects to the array, or edit the result.
- Whole numbers are int in Pydantic only because every sample value was whole. If a field can hold prices or ratios, change it to float.
- Strings that hold dates, enums or IDs stay string. Narrow them by hand if you need a literal union or a branded type.
- JSON cannot show a tuple or a fixed-length array, so those come out as a normal array.
FAQ
Is my JSON uploaded anywhere?
No. The types are generated in your browser and your text is never sent to a server.
How does it decide a key is optional?
Only by comparing the objects in the same array. A key found in every object is required, and a key missing from at least one object becomes optional. A single object has nothing to compare, so all its keys are required.
What is the difference between interface and type?
For plain object shapes they behave the same. An interface can be extended and merged by name, while a type alias cannot be reopened. Use whichever your project style prefers.
Why is a field typed unknown[]?
The array in your JSON was empty, so there was no item to read the type from. Put one example item in the array and the type is filled in.
Can I use the Zod schema to validate data?
Yes. Import z from zod, then call RootSchema.parse(data) or safeParse. The exported type is inferred from the schema, so you do not need to keep two definitions.
Which Pydantic version does the output target?
Pydantic v2 with built-in list[...] generics (Python 3.9 or newer). Fields that can be null are Optional with no default, and keys missing from some objects default to None.