Search tools

Find and open any DevTooKit tool. Use arrow keys to navigate.

Home / Guides

What JSON-to-TypeScript cannot infer

Sumit Jha · Updated 2026-11-06

JSON has no type declaration. A converter looks at one value and picks a TypeScript type that accepts that value. If a field is absent in the sample, it will be absent in the interface. If it is null once, you may get null instead of string | null across the real API. Treat the output as a draft, then widen it.

Open JSON → TypeScript

One sample is one shape

Suppose a user payload sometimes includes phone and sometimes does not. If the sample you paste includes phone, the generated interface marks it as required. Callers that omit phone will not match production. If the sample omits phone, the interface forgets the field and you will not autocomplete it.

The same trap hits unions. An id that is a number in the fixture and a string in the next response becomes number. Enums become the single literal you happened to paste, or a widened string, depending on the generator. Neither result is the full contract.

{ "id": 1, "name": "Ada" }
// phone is missing, so the interface will not mention phone

Numbers, null, and empty arrays

JSON numbers are not int and float. A generator that emits number is usually right for TypeScript and wrong if you needed a bigint or a decimal library. null is its own type. A field that is null in the sample should become something | null, not any, and not a deleted field.

An empty array has no element type. The honest output is unknown[] or never[] until you paste an element. Nested objects should become named interfaces so you can edit them. A single inline object type is harder to reuse.

Types disappear at runtime

A TypeScript interface does not check a response at runtime. If you need a parse step, generate a Zod scaffold from the same sample and then add .optional(), unions, and refinements. The scaffold has the same blind spots as the interface: it only saw one object.

Format the JSON first if you are fighting a syntax error. A converter is not a repair tool. Invalid JSON should fail, not become a guessed type.

Widen a sample before you commit it

Paste one complete object, generate the interface, and then paste a second response that omits a field and a third that uses null. Diff the three outputs. Every field that flickered between present, absent, and null needs a decision: required, optional, or nullable. The generator will not make that decision because each run only saw one value.

Dates are strings in JSON. A field named createdAt becomes string, which is correct and also useless if you meant a Date. Leave it as string and parse it at the boundary, or brand the type yourself. Integers that exceed Number.MAX_SAFE_INTEGER should become string or bigint in your hand-written type. The converter will happily emit number and lose precision at runtime, which TypeScript will not catch.

If you also generate Zod, start from the same sample and then add .optional() and unions to match the diff. A scaffold that parses the fixture and rejects production traffic is the usual outcome of shipping the first draft. The formatter is the right previous step only when the sample does not parse. It will not invent the missing fields.

Keep the sample next to the type in the same change. A future reader needs to see which response the interface came from, because the type does not record the responses you did not paste. Arrays of objects are the sharp case: the generator unions keys it saw on any element only if you gave it more than one element. One element makes every sibling look required. Extra fields that appear only in errors, such as a message on a failure body and a data object on success, need a union you write yourself. The tool’s job is the first draft of the happy path.

FAQ

Will the converter mark optional fields?

Only if the sample shows absence or null in a way the generator understands. A complete sample makes every present key look required.

Is the output safe to commit as the API contract?

Use it as a draft. Compare it with the API docs or with several real responses before you export it as the contract.

Related tools

  • JSON → ZodGenerate Zod schemas from JSON. Auto-detects dates, UUIDs, emails, URLs. With z.coerce option.
  • JSON FormatterBeautify, minify, and validate JSON. Catch syntax errors with line-precise feedback.

Limitation: this note describes the DevTooKit tool and the general rule behind it. Production libraries, clocks, and schedulers can differ. Check those docs before you ship.