Lintify Logo
Lintify
Code Generators

JSON to TypeScript Interfaces

Generate TypeScript interfaces and types from any JSON document. Handles unions, optional fields, enums, and nested objects out of the box.

JSON input
1
TypeScript
Output will appear here…

Generate TypeScript interfaces from JSON

Hand-writing TypeScript interfaces for API responses is tedious and error-prone. You paste a sample response into your editor, then transcribe every field name and guess at the type, hoping you do not miss any optional fields. Lintify automates that: paste a sample JSON document, and the generator walks the structure recursively to produce a TypeScript interface per object shape, with the right types for primitives, arrays, and nested objects.

If you paste a JSON array of objects, the generator merges the keys of every object in the array. Any key that is missing from at least one element is marked optional (with a ?). This is more accurate than picking one element as the source of truth, because real API responses often have nullable or omitted fields.

Union types for mixed samples

If a field has different types across samples — a string in one object and a number in another — the generator emits a union type (string | number). This is more useful than picking one type and silently breaking on the other input. The TypeScript compiler will force you to handle both cases, which is what you want for data you do not control.

String literal unions instead of enums

Lintify emits string literal unions (type Status = 'active' | 'inactive') rather than TypeScript enums. This matches the modern recommendation — literal unions are lighter at runtime (no generated object), work better with type narrowing, and are easier to refactor. If you need a real enum for runtime reflection, the conversion is trivial in your editor.

Interface naming

The top-level interface is namedRootObject by default. Nested objects get names derived from their parent key — for example,users[0].address becomes an interface namedAddress. You can rename them after generation to match your codebase conventions. The names are unique within the generated file, so collisions are resolved by appending a numeric suffix.

Frequently asked questions

Common questions about the JSON → TypeScript tool.

How does the generator pick interface names?
Lintify uses the root key of the JSON document (or a default like RootObject if the document is an array) as the top-level interface name. Nested objects get names derived from their parent key — for example, users[0].address becomes an interface named Address. You can rename them after generation to match your codebase conventions.
How are optional fields detected?
When you paste a JSON array, Lintify merges the keys of every object in the array. Any key that is missing from at least one element is marked optional (with a ?) in the generated interface. For a single object, every key is required because there is no other sample to compare against.
Are unions of types supported?
Yes. If a field has different types across samples (for example, a string in one object and a number in another), Lintify emits a union type (string | number). This is more useful than picking one type and silently breaking on the other input.
Can I use enums for known string values?
Lintify emits string literal unions (type Status = 'active' | 'inactive') instead of TypeScript enums, because literal unions are the modern recommendation and work better with type narrowing. If you need a real enum, the conversion is trivial in your editor.
Does it support readonly fields and nullability?
By default, every field is mutable and null values produce a nullable type (string | null). You can toggle readonly on if you want the resulting types to represent immutable data, which is the safer default for API responses.

Related tools