JSON to TypeScript

Types inferred honestly, not from element one.

Declare as

Types inferred honestly, not from element one.

How to use it

  1. Paste a sample. One real response is enough. The shape is inferred from it.
  2. Name the type. Anything that is a valid identifier. Root if you leave it empty.
  3. Paste it into your project. Then widen anything the sample happened not to cover.

When you would use this

Inferring a type from one JSON sample is guesswork, and a good tool is one that guesses conservatively and does not hide it. Two places where most versions are careless. A mixed array typed from its first element produces a type that is wrong about the very sample it was generated from, so arrays here become a union of everything found in them. And an empty array cannot be inferred at all, so it becomes unknown rather than any: unknown makes the compiler ask you what belongs there, which is correct, because only you know. An interface can only describe an object. Given an array or a primitive at the root, the output switches to a type alias and says why, rather than emitting an interface that will not compile. Keys that are not valid identifiers are quoted. Nested objects are inlined and indented rather than split into separate named types, which keeps the output readable for a sample and is worth extracting by hand once it grows. One sample is a first draft. A field that is null here types as null, and an optional field that happens to be present types as required.

Questions

How are mixed arrays handled?
As a union of every element type it found, so an array holding a number and a string becomes a union of both. Typing from the first element is the usual shortcut and it produces a type that is wrong about its own sample.
Why is an empty array unknown rather than any?
Because there is genuinely nothing to infer from it, and unknown says so where any pretends otherwise. You will get a compiler error the moment you use it, which is the right outcome: only you know what belongs in there.
Is one sample enough?
It is a starting point, not a specification. A field that is null in your sample types as null, and an optional field that happens to be present types as required. Treat the output as a first draft and widen it where you know the shape varies.