Search DevTools

Jump to any tool or page

JSON → TypeScript Converter

Paste JSON and get clean TypeScript types with unions, optionality, and more.

Settings

Options

Input

paste your JSON

Output

Convert your JSON and the types appear here.

Send toZod schema

About the JSON → TypeScript Converter

This tool allows developers to take raw JSON objects—like API responses, configuration files, or mock data— and instantly generate clean, strongly typed TypeScript interfaces. Instead of writing types by hand, you can copy and paste JSON and get ready-to-use definitions.

Key Benefits

Faster development: Stop wasting time manually writing out types.
Safer code: Catch type errors at compile time instead of runtime.
Maintainable: Works great for large and nested JSON structures.
Smart inference: Detects optional properties and generates string literal unions.

Example Use Case

Suppose your API returns the following JSON:

[
  { "id": 1, "status": "open", "user": { "name": "Ada" } },
  { "id": 2, "status": "closed", "user": { "name": "Grace", "email": "g@x.dev" } }
]

The tool will generate TypeScript types like:

export interface Root extends Array<RootItem> {}
export interface RootItem {
    id: number
    status: "open" | "closed"
    user: User
}

export interface User {
    name: string
    email?: string
}

Notice how email becomes optional (email?: string) because it's not present in every object.

When to Use

  • Quickly typing new API endpoints during frontend development
  • Generating models for mock data or testing
  • Documenting backend responses for better DX
  • Refactoring untyped JavaScript projects to TypeScript

FAQ

Does it support arrays at the root?

Yes, root-level arrays are automatically typed as Array<T> with smart inference for their items.

What about deeply nested objects?

Nested objects are expanded into their own interfaces. Identical shapes are de-duplicated where possible to avoid repetition.

Can I use the generated types directly in my project?

Absolutely! Just copy or download the output and drop it into your TypeScript project.

Data Transformation

About JSON to TypeScript

Paste a JSON sample and generate matching TypeScript interfaces, with nested objects lifted into their own named types. The structural limit is worth stating plainly: a single sample is one observation of an API, and it cannot tell you which fields are optional, which are nullable, or which hold a union of shapes — only which values happened to be present in that one response.

Frequently asked questions

Why are all generated fields required when the API returns them optionally?
Because a sample records presence, not contract. A key present in the sample is emitted as required; a key absent from it is not emitted at all. Neither reflects the API's actual optionality. This produces the worst failure mode in typed code: a type that compiles but lies, so code accessing response.user.avatar passes the checker and throws at runtime. Generating from several samples, or marking fields optional by hand against the real documentation, is the only reliable correction.
How should null values in the sample be typed?
A field whose sample value is null carries no type information — you know it can be null and nothing else, so the honest output is null alone, which is useless. Most generators emit any or a nullable guess. The deeper distinction is that TypeScript separates null from undefined: a nullable field is present with value null and typed string | null, whereas an optional field may be absent and typed name?: string. JSON has only null, so the mapping is genuinely ambiguous.
What happens with arrays of mixed or empty contents?
An empty array gives nothing to infer from, so it becomes any[] or unknown[]. A heterogeneous array is harder: generators either union the element types, producing (Foo | Bar)[], or merge all keys into one type with everything optional, which loses the discrimination between variants. The merged form is more convenient and less correct. If the API returns a tagged union, the useful output is a discriminated union keyed on the tag field, which needs to be specified rather than inferred.
Why do large integer IDs lose precision when I test the generated types?
TypeScript's number is a double, and so is the result of JSON.parse, so any integer above 2^53-1 rounds silently on parse. A 64-bit snowflake ID such as 1234567890123456789 becomes a different number before your typed code ever touches it — the type is correct while the value is wrong. Nothing at the type level can prevent this. APIs emitting large IDs should send them as strings; if yours does not, type the field as string and parse with a JSON reviver that preserves the raw text.
Should I use interface or type, and does it matter here?
For plain object shapes they are near-equivalent. Interfaces support declaration merging, so a later declaration of the same name extends rather than replaces it — useful for augmenting third-party types, hazardous when a generator overwrites files and two definitions silently combine. Type aliases cannot merge, so a duplicate name is a clear error, and they express unions and mapped types that interfaces cannot. For generated code, aliases fail louder, which is generally what you want.