# JSON to Types

Convert a JSON sample into TypeScript interfaces and a matching Zod schema. Merges every element of an array into one union rather than typing from the first, distinguishes absent keys from null values, names nested types from their key path, and flags the places where a single sample cannot tell you the real type.

**Not for:** Does not infer types from a JSON Schema or an OpenAPI document — it works from concrete sample data. Does not validate data against a schema, and does not generate types for languages other than TypeScript.

## Surfaces

- HTML: `https://json-to-types.gumballtools.com`
- Markdown: same URLs with `Accept: text/markdown` or `?format=md`
- JSON API: `https://json-to-types.gumballtools.com/api/v1/convert`
- OpenAPI: `https://json-to-types.gumballtools.com/.well-known/openapi.json`
- MCP: `https://json-to-types.gumballtools.com/api/mcp`

## Worked examples

- [JSON to a TypeScript interface](https://json-to-types.gumballtools.com/types/json-to-typescript-interface) — The basic case: a flat object of scalars becomes one interface with the same keys.
- [Nested JSON to TypeScript](https://json-to-types.gumballtools.com/types/nested-json-to-typescript) — Nested objects are hoisted into their own named interfaces rather than inlined, so the output stays readable.
- [A JSON array to a TypeScript type](https://json-to-types.gumballtools.com/types/json-array-to-typescript) — Every element is merged into one type. Typing from the first element alone is the most common way to get this wrong.
- [JSON to a Zod schema](https://json-to-types.gumballtools.com/types/json-to-zod-schema) — The same inference, emitted as a runtime validator. Optional and nullable are kept distinct.
- [Optional vs nullable fields](https://json-to-types.gumballtools.com/types/optional-vs-nullable) — A missing key is optional; a null value is nullable. They are different types, and conflating them is a common source of runtime surprises.
- [A JSON array with mixed types](https://json-to-types.gumballtools.com/types/mixed-type-json-array) — Arrays holding more than one type become a union of everything observed, not just whatever came first.
- [JSON containing an empty array](https://json-to-types.gumballtools.com/types/json-with-empty-array) — An empty array carries no information about its elements. The output says so rather than inventing a shape.
- [An API response to TypeScript](https://json-to-types.gumballtools.com/types/api-response-to-typescript) — The common paginated-envelope shape: a wrapper object with a data array and page metadata.
- [JSON with hyphenated or reserved keys](https://json-to-types.gumballtools.com/types/json-with-hyphenated-keys) — Keys that are not valid identifiers get quoted in both outputs and need bracket access.
- [Deeply nested JSON](https://json-to-types.gumballtools.com/types/deeply-nested-json) — Names are derived from the key path so deep structures stay legible, and the depth itself is flagged.
- [JSON with repeated shapes](https://json-to-types.gumballtools.com/types/json-with-repeated-shapes) — Structurally identical objects share a single interface instead of being duplicated per key.
- [A webhook payload to TypeScript](https://json-to-types.gumballtools.com/types/webhook-payload-to-typescript) — Event envelopes usually nest the interesting data two levels down, and the type name should follow.
- [Are JSON numbers integers or floats?](https://json-to-types.gumballtools.com/types/json-numbers-integer-or-float) — JSON has one number type. Whole values in a sample do not prove a field is an integer.
- [GeoJSON to TypeScript](https://json-to-types.gumballtools.com/types/geojson-to-typescript) — Coordinate arrays and nested feature objects, a shape people convert constantly.

