JSON to TypeScript
Free online JSON to TypeScript converter that auto-infers JSON data into standard TS interface declarations. Supports nested sub-interfaces, union array types, optional and readonly fields, 2/4-space indent options, and runs 100% in your browser without uploads.
Related
About JSON to TypeScript: turn JSON data into TS types automatically
JSON to TypeScript is the process of converting JSON-formatted data (JSON objects or JSON arrays) into TypeScript interface declarations. JSON (JavaScript Object Notation) is the standard data format for REST APIs, configuration files, and logs, while TypeScript is a statically typed superset of JavaScript. In everyday development, writing TS interfaces by hand from API JSON is error-prone and time-consuming; this tool automates that workflow.
At its core, the tool infers the structure of a JSON object and emits a TypeScript interface. Each object key becomes an interface property; each value's literal type is mapped to its TS counterpart: strings become `string`, numbers become `number`, booleans become `boolean`, null becomes `null`, arrays become `T[]`, and nested objects become independent sub-interfaces. The whole process runs locally in your browser, no backend required, and produces a complete, usable type definition in seconds.
Type inference is the heart of JSON to TypeScript. JSON has only six primitive types (null, boolean, number, string, array, object), while TypeScript's basic type system includes string, number, boolean, null, undefined, any, unknown, void, never, object, Array, T[], union types (A | B), and more. The tool's getTsType function maps each value based on its typeof and shape: typeof null maps to `null`; typeof undefined maps to `undefined`; typeof boolean maps to `boolean`; typeof number maps to `number`; typeof string maps to `string`; Array.isArray() triggers array handling.
Nested object handling is a key capability. When the JSON contains nested objects, the tool recursively generates independent sub-interfaces to avoid duplication. For example `address: { street, city }` produces a RootAddress sub-interface, and the main interface references it via `address: RootAddress`. Sub-interface names follow the convention of parent name + field name in PascalCase. A processedTypes Set is used for de-duplication so identical nested structures only produce one interface.
Array type inference has three modes. First, empty arrays fall back to `any[]` because there is no element type to inspect. Second, when all elements share the same type the result is `T[]` (for example `string[]` or `User[]`). Third, when element types differ the result is a union array `(A | B)[]` (for example `(string | number)[]`). This distinction keeps the output both accurate and readable while avoiding unnecessary `any[]`.
Optional fields (?) are important under TypeScript strict mode. When the option is on, the tool scans every field's value; if it sees null or undefined it appends `?` to that field in the interface, e.g. `name?: string` means the field can be missing. This is invaluable for backend APIs that return optional fields and prevents runtime errors when accessing undefined properties. Readonly fields (readonly) emphasize immutability, producing code like `readonly id: number` for configuration, state snapshots, or DTOs.
interface vs type alias is a common choice for TypeScript users. The tool generates interfaces because they are the standard way to describe object shapes: they support declaration merging, the implements keyword, and extends inheritance, and they match the conventions of React, Vue, and Angular projects. Type aliases shine for union and intersection types and function signatures, but for object types interface is the preferred choice.
Real-time conversion is a practical feature. The tool converts 400ms after typing stops, with no button click required. Combined with CodeMirror's TypeScript syntax highlighting (via @codemirror/lang-javascript with typescript: true), users can immediately see the generated interface and iterate quickly. This feedback loop dramatically accelerates type design.
JSON error self-repair boosts the tool's resilience. Real-world JSON often has trailing commas, single quotes, missing quotes, or comments. The built-in tryFixJSON routine kicks in when JSON.parse fails and tries to fix common mistakes; if the repair succeeds the user is notified; if not, the right panel shows the exact error location and reason. This design pushes the tool's practical success rate up and removes the back-and-forth of fixing small mistakes manually.
Pure client-side processing is the core architectural decision. All JSON parsing, type inference, and interface generation run in browser JavaScript; nothing is ever sent to a server. The two key benefits: first, the JSON may contain sensitive data (API keys, tokens, user records) and local processing removes any leak risk; second, the conversion speed is limited only by the device's CPU, so files under 1 MB finish almost instantly. This is a strict improvement over online services that require sign-in or upload user data.
Use Cases
- Quickly convert REST API or GraphQL JSON responses into TS interfaces during frontend development, avoiding hand-written type definitions.
- Generate TS types for React/Vue/Angular component Props, State, and parameters from sample JSON in seconds.
- Share types between frontend and backend in a full-stack TypeScript project, using backend mock JSON as the single source of truth.
- Generate TypeScript interfaces when integrating third-party APIs (shipping, weather, payments) without reading lengthy docs.
- Reverse-engineer type definitions from mock data, test fixtures, or JSON configuration files to strengthen type safety and IDE hints.
- Convert database ORM JSON Schema exports into TypeScript interfaces for Node.js backend DTO definitions.
- Learn TypeScript by turning existing JSON into interface examples to understand nested types, unions, and optional fields.
- Refactor loose JS object literals into formal interfaces to improve code readability and type safety.
How to Use
- Paste JSON into the left editor, click the Upload button to select a .json/.txt file, or click Sample to load the built-in example.
- Click the interface name button on the right of the toolbar (or the gear icon) to rename the root interface (default Root) and toggle optional / readonly fields.
- The tool converts automatically with a 400ms debounce. View the generated TypeScript interface on the right with CodeMirror highlighting.
- Switch between 2-space and 4-space indent from the toolbar, and adjust the split between left and right panels for the best view.
- Click Copy to put the TS code on the clipboard, or click Download to save it as a `${interfaceName}.ts` file (e.g. User.ts).
- Paste the code into your project's `types/` or `src/types/` directory and import it where needed.
Features
- Smart type inference: automatically recognizes null, boolean, number, string, array, and object and maps them to native TS types.
- Nested object expansion: each nested object becomes its own sub-interface (e.g. RootAddress) for a clean, non-duplicated type hierarchy.
- Array type intelligence: homogeneous arrays become `T[]`, mixed-type arrays become union arrays `(A | B)[]`, empty arrays fall back to `any[]`.
- Optional field marking: when enabled, null or undefined fields get the `?` modifier, producing code that complies with TypeScript strict mode.
- Readonly field support: when enabled, every field gets the `readonly` modifier, ideal for immutable state, configuration, and DTOs.
- Custom interface name: the root interface name is configurable (default Root) and the downloaded file is named after it (e.g. User.ts).
- 2/4-space indent options: switch between 2-space (ESLint default) and 4-space indentation from the toolbar.
- Real-time auto conversion: the tool converts 400ms after typing stops, supporting paste, file upload, and sample loading.
- JSON error self-repair: the built-in tryFixJSON routine handles trailing commas, single quotes, and missing key quotes automatically.
- TypeScript code highlighting: the right editor uses CodeMirror with the TypeScript language extension for clear syntax coloring.
- Copy and download: copy the result to the clipboard with one click or save it as a standard .ts file ready for your project.
- 100% browser-side: all parsing, inference, and interface generation happen in client-side JavaScript; the original JSON never leaves your device.
FAQ
How do I convert JSON into a TypeScript interface?
Paste your JSON into the left editor and the tool automatically infers the type of every field (string, number, boolean, array, object, etc.) and generates a standard TypeScript interface. Nested objects are extracted into separate sub-interfaces that keep the type hierarchy clean. The conversion runs automatically 400ms after typing, so no button click is required.
Does the tool generate type aliases or interfaces?
This tool exclusively generates TypeScript interface declarations (type aliases are not produced). Interfaces are the standard way to describe object shapes in TypeScript: they support declaration merging and the implements keyword, and they are the preferred choice in React, Vue, Angular, and other modern frontend projects.
How do I mark fields as optional?
Enable "Optional fields (?)" in the settings panel. The tool then scans every field's value and, when it finds null or undefined, automatically adds the `?` modifier to the interface. For example `name?: string` means the field can be missing. The output complies with TypeScript strict mode.
How do I generate readonly fields?
Enable "Readonly fields (readonly)" in the settings panel. Every field then gets the `readonly` modifier, for example `readonly id: number`. This emphasizes immutability and is ideal for configuration, state snapshots, or DTO definitions.
How does the tool handle arrays?
The tool analyzes the element types of each array. When all elements share the same type it emits `T[]` (e.g. `string[]`); when types differ it emits a union array `(A | B)[]` (e.g. `(string | number)[]`); when the array is empty it falls back to `any[]`.
Does a nested object become its own interface?
Yes. Every nested object becomes its own sub-interface named by combining the parent interface name with the field name in PascalCase. For example, a Root interface containing an `address` object produces both Root and RootAddress. The main interface references the sub-interface, avoiding type duplication.
Can I customize the interface name?
Yes. Click the interface name button on the right of the toolbar (or open the settings dialog) to rename the root interface (the default is Root). The downloaded .ts file will be named after this value too (for example User.ts). Sub-interface names are derived automatically from the root.
Can the downloaded .ts file be used directly in a project?
Yes. The generated code follows TypeScript best practices, includes complete type definitions, nested interfaces, and union types, and can be pasted into React, Vue, Angular, or Node.js projects as is. The download is named `${interfaceName}.ts`, e.g. User.ts.
What if my JSON fails to parse?
When the JSON contains trailing commas, missing quotes, or single quotes instead of double quotes, the tool automatically calls tryFixJSON to attempt a repair. If the repair succeeds, you will be notified; if not, the right panel shows the exact error location and reason. You can also use the 2/4-space indent to reformat and try again.
Which JSON structures are supported?
All valid JSON is supported: primitives (null, boolean, number, string), arrays of any depth, nested objects at any depth, and mixed-type arrays (which become union types). Invalid inputs such as functions, Symbols, or undefined values are not part of the JSON specification and are not accepted.
Can I choose the indent size?
Yes. A dropdown in the right toolbar lets you switch between 2-space and 4-space indentation. Two spaces match the ESLint/Prettier default; four spaces suit projects that prefer a wider indent. The generated code is consistently indented for readability.
How does this differ from JSON Schema or Zod?
JSON Schema is great for runtime data validation (API boundaries, user input). Zod and yup are TypeScript-friendly runtime validators that can derive TS types from a schema. This tool is a lightweight pure type-definition generator; it does not perform runtime checks, focuses on frontend static typing, is faster, and has zero dependencies.
Troubleshooting
The generated interface looks wrong. What should I do?
Common causes: JSON parse failure, nested object misidentification, or wrong array type inference. Try these steps: 1) Validate the JSON with a JSON formatter; 2) For nested objects, double-check the sub-interface references; 3) For arrays, confirm the element types are consistent; 4) Regenerate or hand-edit the output. The interface is a first draft, so always adjust details against the real API.
The downloaded .ts file fails to compile in my project.
Likely causes: 1) tsconfig.json does not have strict mode but the generated code uses readonly; 2) the interface name clashes with an existing type; 3) a field name is a TypeScript keyword (such as class or type). Fix by adjusting strict mode, renaming the interface, or quoting the conflicting field (e.g. "class": string).
JSON contains nested arrays but the inferred type is wrong.
The tool handles multi-dimensional arrays (e.g. [[1, 2], [3, 4]]) recursively and produces number[][]. If nested array element types differ, the tool emits ((A | B)[])[] . Empty arrays always become any[] because there is no element type to infer.
null values are mapped to `null` type instead of optional fields.
By default, the tool maps JSON null values to the TS `null` type (e.g. middleName: null). To produce optional fields instead: 1) enable the Optional fields option (recommended); 2) remove the null values from the JSON so the field is missing; or 3) after generation, manually change `null` to `string | null` or use `?`.
The interface name and the download filename don't match.
Both are driven by the same value, the Interface Name setting (default Root). The downloaded file is named `${interfaceName}.ts`. If they appear out of sync, check whether the tool is open in multiple tabs with different settings. Re-open the page or refresh the settings to align them.
The generated code is full of `any` types.
Likely causes: 1) the JSON contains values the parser couldn't recognize; 2) arrays are empty so they fall back to any[]; 3) fields are null and the optional option is off. Fix by checking data integrity, adding more sample data to improve inference, or manually specifying types for fields that are always empty (e.g. User[]).
How do I merge the generated interface with an existing type?
TypeScript interfaces support declaration merging: same-name interfaces automatically merge their members. Just declare a same-name interface in your project and export it; for example, the tool emits `export interface User { id: number }` and you write `export interface User { name: string }`, and they merge into `{ id: number; name: string }` automatically.
Glossary
- JSON (JavaScript Object Notation)
- A lightweight data-interchange format based on JavaScript object syntax but independent of any programming language. Supports six basic types: object ({}), array ([]), string, number, boolean, and null. Widely used for REST APIs, frontend-backend transport, configuration files, and logs.
- TypeScript
- A JavaScript superset developed by Microsoft that adds static type definitions, interfaces, generics, and other features. TypeScript code is compiled to plain JavaScript and runs in the browser or on Node.js. It is the language of choice for modern frontend projects built with React, Vue, and Angular.
- interface
- A TypeScript keyword that describes the shape of an object. Syntax: `interface Name { prop: type; }`. Supports declaration merging (same-name interfaces auto-merge), the implements keyword (classes implementing an interface), and extends inheritance. The primary way to describe object types in TypeScript.
- type alias
- A TypeScript keyword that assigns a name to a type. Syntax: `type Name = ...`. Useful for union types (A | B), intersection types (A & B), and function types. More flexible than interface but does not support declaration merging. This tool exclusively emits interfaces.
- Type inference
- The process this tool uses to decide the TS type for each JSON value based on its typeof and shape. For example, typeof string maps to string, Array.isArray() triggers array handling, and typeof object triggers a new sub-interface.
- Optional field (?)
- A TypeScript modifier that marks a field as possibly missing. `name?: string` means the name field may not exist (its value is undefined). When the tool's optional field option is on, fields whose value is null or undefined automatically get the `?` modifier.
- Readonly field (readonly)
- A TypeScript modifier that marks a field as immutable after object creation. `readonly id: number` means id cannot be reassigned. When the tool's readonly option is on, every field automatically receives the `readonly` modifier.
- Union type
- A TypeScript type that allows a value to be one of several types. Written as `A | B`. The tool uses this notation when array elements have different types, e.g. `(string | number)[]`.
- Array type
- The TypeScript syntax for arrays, available in two forms: the generic form `Array<T>` and the short form `T[]`. The tool always uses the short form and has three array-type generation modes: homogeneous `T[]`, mixed `(A | B)[]`, and empty `any[]`.
- Nested interface
- An interface that references other interfaces to form a type hierarchy. The tool produces a sub-interface for every nested object, and the main interface references them by property name. For example, Root references RootAddress, and RootAddress can be reused independently elsewhere.
- TypeScript strict mode
- A collection of strict compiler options in TypeScript (noImplicitAny, strictNullChecks, strictFunctionTypes, and more). With strictNullChecks enabled, null and undefined are independent types and cannot be assigned to other types. The optional fields produced by this tool are fully compatible with strict mode.
- DTO (Data Transfer Object)
- An object used to transfer data between layers (for example, between an API and a service). TypeScript projects typically describe DTOs with interfaces, often using readonly to enforce immutability. This tool is a common choice for generating DTO type definitions.
- Declaration merging
- A TypeScript feature for interfaces: same-name interfaces automatically merge their members. Commonly used to extend third-party library type definitions. The interfaces produced by this tool can be merged with same-name interfaces in your project, enabling gradual type extension.
- tsconfig.json
- The TypeScript project configuration file at the project root. It contains compilerOptions (target, module, strict, and more), include, and exclude settings. The .ts files produced by this tool work in any standard tsconfig project.
- tryFixJSON
- The tool's built-in JSON repair routine that handles trailing commas, single quotes used instead of double quotes, missing key quotes, comments, and other common JSON syntax errors. It runs automatically when JSON.parse fails; if the repair succeeds, the user is notified and the conversion continues.
JSON-to-TypeScript type mapping rules
The full set of rules the getTsType function uses to map JSON values to TypeScript types:
| JSON value | Example | TypeScript type | Detection rule |
|---|---|---|---|
null | null | null | JSON null maps directly to TS null |
undefined | undefined | undefined | undefined values map to TS undefined (only at runtime) |
boolean | true / false | boolean | typeof boolean maps to TS boolean |
integer | 1, 100, -9999 | number | Integers and floats both map to TS number |
float | 3.14, -0.5, 1e10 | number | All number literals map to number (TS does not distinguish int/float) |
string | "Alice", "Beijing" | string | typeof string maps to TS string |
empty array | [] | any[] | Empty arrays fall back to any[] |
homogeneous array | [1, 2, 3] | T[] (e.g. number[]) | Same-type elements produce a single array type |
mixed array | [1, "a"] | (A | B)[] (e.g. (number | string)[]) | Mixed-type elements produce a union array |
object | {a: 1, b: "x"} | SubInterface (e.g. Root) | Nested objects become independent sub-interfaces that are referenced |
interface vs type alias comparison
Why this tool generates interface instead of type alias, and how the two compare in TypeScript projects:
| Capability | interface | type alias | Notes |
|---|---|---|---|
| Object shape description | ✓ (preferred) | ✓ (also supported) | Both work; this tool emits interface |
| Declaration merging | ✓ (same-name auto-merges) | ✗ (duplicate declaration errors) | Interface supports gradual extension |
| implements/extends | ✓ (classes can implements) | △ (only object types can be implements) | Interface is more natural in OOP |
| Union types (A | B) | ✗ | ✓ | Type is more concise for unions |
| Intersection types (A & B) | ✗ | ✓ | Type is more concise for intersections |
| Function types | △ (needs call signature) | ✓ (direct) | Type is more intuitive for functions |
| Performance (large type sets) | slightly faster | slightly slower | Interface merges incrementally at compile time |
| This tool's choice | ✓ unified use | ✗ | This tool focuses on object types; interface is the best fit |
Optional and readonly field generation rules
How the two toggle options affect the generated code and when to use each:
| Option | Trigger | Generated syntax | Best for |
|---|---|---|---|
| Optional (?): off | (default) | name: string | Strict, all fields required |
| Optional (?): on | value === null || value === undefined | name?: string | Optional fields, missing data |
| Readonly: off | (default) | name: string | General types, fields writable |
| Readonly: on | applies to every field | readonly name: string | Immutable state, config, DTOs, API responses |
| Both on | both conditions apply | readonly name?: string | API response snapshots, optional config |
Privacy & Security
This JSON to TypeScript tool runs entirely in your browser. JSON parsing, type inference, and interface generation all happen in client-side JavaScript; nothing is sent to any server. File uploads use the native FileReader API and never go through an intermediate service. The tool uses no tracking cookies and collects no input or usage data. All input and output are cleared from memory as soon as the page is closed or refreshed. Safe to use for JSON that contains API keys, tokens, or other sensitive business data.
Authoritative References
- JSON Compress
- CSV to JSON
- JSON to CSV
- JSON Diff
- JSON Escape / Unescape
- JSON Flatten
- JSON Formatter
- JSON Generator
- JSONPath Query
- JSON Merge
- JSON Repair
- JSON Schema Validator
- JSON Sort
- JSON Stringify
- JSON to HTML Table
- JSON to Java
- JSON to Markdown
- JSON to SQL
- JSON to TOML
- JSON to TypeScript
- XML to JSON
- JSON to XML
- YAML to JSON
- JSON to YAML
- JSON to Python
- JSON to Go
- JSON to Rust
- JSON to Swift
- JSON to C#
- JSON to C++
- JSON to PHP