TheDevTab
Tools

Search tools and guides

Ctrl K

Keyboard shortcuts

Ctrl K
Search tools and guides
?
Show keyboard shortcuts
Escape
Close menus and dialogs

Guide

Generate types from JSON

By TheDevTab team · Updated 21 August 2026

Start with evidence, not a contract

A JSON sample shows values that appeared once. It does not show whether a missing property is optional or simply absent from the example, whether a property can be null, or whether an empty array normally contains strings, objects, or several kinds of value. It also cannot reveal union members that were not sampled. A field containing 3 may be an arbitrary-precision identifier, a 32-bit count, or a value that later exceeds the range of an inferred language type. A date, UUID, and opaque token are all just strings in JSON.

Arrays need the same caution. One sample element does not prove that every element has the same shape, and an empty array provides no element evidence at all. A single object tends to make every observed key look required, while a sample containing several objects can show that a key is absent from some records. Collect representative success responses, error responses, pagination variants, and records from different states before treating generated code as a design decision.

TheDevTab's type generators parse JSON and produce draft declarations in your browser. Nothing is uploaded. Use JSON Formatter to check the sample's syntax first, but remember that valid JSON says nothing about whether the values satisfy an API contract.

TypeScript records presence separately

TypeScript uses an optional property marker for a key that may be omitted:displayName?: string. That is different from a required property whose value may be undefined, written as displayName: string | undefined, and both differ from displayName: string | null. JSON has no undefined value, so an API usually needs a clear distinction between a missing key and an explicit null. With strictNullChecks and exactOptionalPropertyTypes, those distinctions become especially visible in assignments and reads.

JSON to TypeScript generates interfaces by default and can switch to type aliases. For an object sample, observed properties are required by default; the “All properties optional” option changes them to ?. For arrays of objects, the generator merges keys across the sampled objects and marks a key optional when it was not present in every object. A sampled null remains null, and an empty array becomes unknown[].

The output is a useful starting point, not a declaration that a server will always send those fields. Add explicit unions for documented variants, brand identifiers where the application needs stronger meaning, and decide whether an optional property should also allow null.

Go needs a policy for missing and null

Go struct fields do not become required merely because a JSON tag exists. During unmarshalling, an omitted field keeps its zero value, and a present value may still be invalid for application rules. A pointer is useful when the program must distinguish “not provided” from a concrete zero value. A pointer can also represent JSON null, although the surrounding decode and validation code must define what nil means.

JSON to Go emits structs with json tags. It infers integer-looking numbers as int and fractional numbers as float64; that choice is based on the sample, not on the producer's numeric width or future range. A sampled null is represented with pointer handling, and an empty array becomes []any. The “All properties optional” option adds omitempty to fields inferred as optional. That tag controls marshaling output; it does not make incoming data required or validate a request.

Review numeric widths and pointer use against the actual Go service.

Python TypedDict expresses key presence

Python's TypedDict describes dictionary keys for static type checkers. A class can use total=False to make all declared keys potentially absent, or modern typing code can use NotRequired[T] for individual optional keys while leaving other keys required. Neither choice changes runtime dictionaries or performs validation by itself. A nullable value is a different concern and should be expressed as a union such as str | None.

JSON to Python emits TypedDict declarations and uses NotRequired[...] for fields that are missing from some sampled objects or when “All properties optional” is enabled. It does not emit a class-level total=False option. It maps strings, booleans, integers, and floating-point samples to corresponding Python annotations, imports Any for empty arrays, and combines observed object shapes into nested declarations.

Check the Python version and type-checker support for NotRequired, and choose compatible imports if the project targets older runtimes. Also decide whether a field that is absent should be handled the same way as one whose value is None; a TypedDict annotation can describe the distinction, but application code still has to enforce it.

Reconcile output with the real schema

A generated declaration becomes trustworthy only after it is compared with the API schema or producer code. Check required keys, nullability, enum values, formats, additional properties, numeric limits, array item unions, and error payloads. If the service publishes OpenAPI or JSON Schema, treat that document as the contract and use samples as tests of the contract rather than as its only source.

JSON Schema Generator can turn representative samples into a draft-07 schema. It marks a property required when it appears in every sampled object, represents observed primitive alternatives as type unions, and can emit additionalProperties: false. Empty arrays produce an unconstrained item schema, and a schema inferred from one sample cannot describe values that never appeared. Review and edit the result before using it for validation.

Finally, keep the generated code under the same tests as the client or server that consumes it. Add fixtures for omitted fields, explicit nulls, empty arrays, mixed unions, large numbers, and unknown keys. Regenerate only when the input evidence and contract review are intentional. That workflow turns a convenient draft into a maintainable type boundary.