JSON to TypeScript
Paste or upload a JSON sample to generate TypeScript types. Runs in your browser.
Pasted text and chosen files stay on this device. Nothing is sent to a server.
Drop a file here, choose one, or paste.
How to use it
- 1
Paste one response.
- 2
Read the optional count, then decide which of those fields to make required — that is a decision about your API, not about the sample.
What it does
The type system is the thing being written to, so the hard parts are the ones TypeScript makes hard: a field observed once is not a field that is always there, an array holding a number and a string is a union rather than one type, and an object whose keys vary needs an index signature rather than a property list.
Walk the sample and emit interfaces. Report, per field: whether it is emitted optional, whether its type is a union, and whether an index signature was needed. Never emit `any` silently.
Why it works this way
A field present in the sample is not a field always present, so fields observed once are emitted with `?`. That is TypeScript's own way of saying it, which is why this decision belongs on this page rather than on the schema page.
An array holding a number and a string becomes `(number | string)[]`, not `any[]`. A union is what the sample actually showed, and it keeps the compiler checking the members.
When a nested object has a varying key set the generator emits an index signature and says so. `unknown` is the value type it prefers, because `any` switches checking off for every member rather than for the one that is uncertain.
null is a member of the type, not an absence. `string | null` and `string?` are different claims and the sample decides which one it supports.
Examples
{"a": 1, "b": null}interface Root {
a: number;
b: null;
}{"a": [1, "x"]}interface Root {
a: (number | string)[];
}{"a": {"k1": 1, "k2": 2}}interface Root {
a: { [key: string]: number };
}Inputs and outputs
- JSON sample
- root type name
- optional marking: observed once / never / always
- index signatures: on / off
- TypeScript source
- counts: fields marked optional, unions emitted, index signatures added
Edge cases
- an array of mixed types — union
- an empty array — the element type is unknowable, reported rather than guessed
- a key that is not a valid identifier — quoted
- null alongside a type
- an object whose keys are all distinct and non-patterned — no index signature
- a field whose only value was a number in one object and a string in another
Frequently asked questions
Why is my field optional?
It was observed once. One observation cannot show a field is always present, so it is emitted with `?` and you can make it required deliberately.
Why an index signature instead of my keys?
The sample's keys looked like a pattern rather than a fixed set. Fixed properties would reject a response with one more key.
Why unknown and not any?
`any` turns checking off for everything that touches it. `unknown` keeps the check on and makes you narrow the type first.
Related tools
Sources
- TypeScript handbook: Everyday Types, Object Types, Index Signatures