JSON to TypeScript & Types
runs in your browserTurn a JSON sample into TypeScript interfaces, Go structs, Rust serde structs, Python dataclasses or Kotlin data classes.
Types are inferred from the sample. Objects in a list are merged, so a key missing from one of them becomes optional.
JSON sample
TypeScript
about this tool
From a sample response to real types
Paste a JSON document and get type definitions for it in TypeScript, Go, Rust, Python or Kotlin. This is the fastest route from "here is what the API returns" to code that will not compile if you misspell a field.
Nested objects become their own named types rather than one inline blob, named from the key they appeared under, so the output reads like something a person wrote.
What each language gets
- TypeScript — interfaces, with optional members marked
? - Go — structs with
json:"..."tags, since Go's exported fields are capitalised and would not otherwise match the payload - Rust — structs with
serdederives and#[serde(rename)]where a field name is not valid Rust - Python — dataclasses with type hints
- Kotlin — data classes
Field names are converted to each language's convention — camelCase for TypeScript and Kotlin, PascalCase for Go's exported fields, snake_case for Rust and Python — while the original JSON key is preserved in whatever annotation the language uses for it.
For a JSON Schema from the same sample — to validate documents rather than type them — use the schema generator.
What a single sample cannot tell you
Generation infers types from the example in front of it, which means it inherits that example's blind spots. Watch for these:
nullin a sample means the field is nullable, but a field that is sometimes null and non-null in your sample will be typed as non-nullable.- An empty array carries no information about what it holds.
- A field missing from the sample cannot be known about at all, so it will be absent from your types rather than optional.
- Numbers are all one type in JSON, so an integer ID and a price are
indistinguishable — worth checking in Go and Rust, where
intandfloat64are different decisions. - Dates are strings in JSON, so they arrive as strings and usually want changing to a real date type by hand.
The practical answer to most of this is to generate from the largest, most representative response you can find, then read the result critically. It is a starting point that saves twenty minutes of typing, not a substitute for the API's documentation.
Nothing is uploaded
The whole thing runs in the page, so a real production response — the one that actually shows you the optional fields — is safe to paste.
questions
- Which languages can it generate types for?
- TypeScript interfaces, Go structs with json tags, Rust structs with serde derives, Python dataclasses and Kotlin data classes. Field names are converted to each language's convention while the original JSON key is kept in the annotation.
- Why is a field typed as non-nullable when the API sometimes returns null?
- Because generation can only see the sample you provided. A field that happens to be non-null in your example is typed non-nullable. Generate from the largest, most representative response you can find, then read the output critically.
- What does it do with an empty array?
- Nothing useful, because an empty array carries no information about what it holds. You will need to fill in the element type by hand.
- Are integers and floating point numbers distinguished?
- Not reliably, because JSON has a single number type. That matters most in Go and Rust, where int and float64 are different decisions, so check numeric fields after generating.
- Why does Go output include json tags?
- Because Go only marshals exported fields, which must be capitalised, and those capitalised names would not match the payload's keys. The json tag maps between them, with omitempty added for optional fields.