JSON to TypeScript Interface Generator
Paste valid JSON and generate readable TypeScript interfaces instantly. Nested objects, object arrays, unions, optional properties, readonly fields, exports, copy, and download all run locally.
Generate TypeScript in real time
The output is inferred from this sample only. Review it against the full API contract.
What this generator infers
The page reads a concrete JSON value and describes its visible shape using TypeScript. Strings become string, finite numbers become number, booleans become boolean, and JSON null becomes null. Objects receive named interfaces, while arrays receive element types. A root primitive or root array is represented by a type alias because an interface can only describe an object-like shape.
Nested interface names are derived from property paths. A user object becomes User; an array stored under orderItems becomes OrderItem. Names are converted to PascalCase and cleaned so the generated identifier begins with a valid TypeScript character. Property names that are not ordinary identifiers are quoted.
user: User;
roles: string[];
}
export interface User {
id: number;
name: string;
}
Arrays, mixed values, and unions
An empty array does not reveal its future element type, so the generator uses unknown[] instead of claiming a string, number, or object. A mixed primitive array can create a union such as (number | string)[]. Parentheses make the intended array element union clear.
For arrays of objects, the generator examines every sample object rather than only the first. Properties missing from some objects become optional. Values observed with different types become unions. This is more informative than copying the first row, but it still reflects only the examples supplied. A later API response may introduce another variant.
Optional and readonly settings
Enable “Make all fields optional” when the target object is a partial update, configuration override, or incomplete draft. This adds a question mark to every property. Optionality discovered from inconsistent array objects is applied even when the global option is off.
Readonly properties prevent ordinary assignment through that TypeScript type; they do not freeze the runtime JavaScript object. The export option adds export before interfaces and aliases so the declarations can be imported from another module. These settings affect generated syntax, not the input JSON.
Using generated types responsibly
- Start with a representative sample containing normal, empty, null, and edge-case values where possible.
- Generate the interfaces, then compare them with the official API schema or backend model.
- Rename generic nested interfaces when domain-specific names would be clearer.
- Decide whether nullable and optional mean different things in the API. A missing field and a field containing null are not identical.
- Add literal unions, branded identifiers, date handling, generics, comments, and validation rules manually where needed.
- Use runtime validation for untrusted data; TypeScript types disappear when JavaScript runs.
Reviewing generated names and future changes
Path-derived interface names are intentionally descriptive, but deeply nested payloads can produce long names. Rename them to stable domain terms such as Customer, InvoiceLine, or PaginationMeta before committing the file. Keep those names independent from one temporary endpoint path when several responses share the same concept. Regenerate or compare types whenever an API version changes, and review the diff instead of replacing a carefully maintained model blindly. Generated declarations are a starting point: comments, imported shared types, deprecated fields, discriminated unions, and business invariants still require human knowledge.
Common inference traps
- Dates: JSON dates are strings. The generator cannot know whether a string should become
Date, remain ISO text, or use a domain-specific type. - Integers: TypeScript uses
numberfor ordinary JSON numbers and does not create an integer type. - Large identifiers: JSON numbers beyond JavaScript’s safe integer range may already have lost precision. APIs should often send them as strings.
- Null-only fields: a sample containing only null provides no evidence for the non-null type.
- Empty objects: an empty object reveals no properties and may require a manually defined record or interface.
Methodology and limitations
Input is parsed with the browser’s native JSON parser. The generator recursively visits values, accumulates interface definitions, merges object-array properties, removes duplicate union members, and emits child interfaces before the root declaration. It does not upload, execute, or evaluate the JSON as JavaScript.
This is a source-code convenience tool, not a schema compiler. It does not consume JSON Schema, OpenAPI, comments, trailing commas, JavaScript object literals, references, discriminators, or custom scalar metadata. Invalid JSON produces a readable parse error and clears stale output.
Frequently asked questions
Why did an empty array become unknown[]?
No element exists from which to infer a type. unknown honestly requires later narrowing and is safer than silently using any.
Why are some properties optional?
When objects in the same sample array do not all contain a property, the generator marks that property optional. You can also make every property optional with the page setting.
Does the output validate API responses?
No. TypeScript checks code during development. Use a runtime validator or schema library before trusting external input.
Can it generate classes?
No. Interfaces and type aliases describe shape without constructors, methods, decorators, or runtime behavior.
Is the JSON stored?
No. Parsing and code generation happen in the current browser page. Avoid confidential production data on an untrusted device.
Why are invalid property names quoted?
Keys containing spaces, hyphens, or leading digits are valid JSON but not plain TypeScript identifiers. Quoting preserves the original key exactly.
Reference
The TypeScript object types documentation explains interfaces, optional properties, readonly properties, and related structural typing behavior. Review the documentation for the TypeScript version used by your project.