// blog/developer/
Back to Blog
Developer · July 19, 2026 · 8 min read · Updated May 22, 2026

Generate TypeScript Types from JSON

Generate TypeScript Types from JSON

You get a JSON response from an API. You need to work with it in TypeScript. You could type the whole thing as any and move on with your life, but then you lose every benefit TypeScript provides: autocompletion, compile-time error checking, and documentation through types.

Writing TypeScript interfaces by hand for a large JSON object is tedious and error-prone. A response with 20 fields, nested objects, and arrays can take 30 minutes to type correctly. And if the API changes, you get to do it all over again.

Type generators solve this by analyzing a JSON sample and producing TypeScript interfaces automatically. Paste in the JSON, get back the types. The process takes seconds and handles edge cases that humans miss, like optional fields and union types.

* * *

How JSON-to-TypeScript Generation Works

The generator analyzes the structure and values of your JSON to infer types:

Primitive values map directly: strings become string, numbers become number, booleans become boolean, null becomes null.

Objects become interfaces with a property for each key. The property types are inferred from the values.

Arrays become Type[] where Type is inferred from the array elements. If the array contains mixed types, the generator creates a union type.

Nested objects become separate interfaces that are referenced by the parent.

Example JSON: `json { "id": 42, "name": "Widget", "tags": ["hardware", "gadget"], "metadata": { "created": "2026-07-19", "active": true } } `

Generated TypeScript: `typescript interface Root { id: number; name: string; tags: string[]; metadata: Metadata; }

interface Metadata { created: string; active: boolean; } `

Before generating types, make sure your JSON is valid. The JSON Schema Validator catches syntax errors and schema mismatches that would cause the generator to fail or produce wrong types.

TypeScript code with type definitions on screen
TypeScript code with type definitions on screen
* * *

Handling Edge Cases and Optional Fields

Real-world JSON is messier than textbook examples. Good generators handle:

Optional fields: if a field is present in some array elements but missing in others, it should be typed as optional (field?: type). Single-sample generators cannot detect this, which is why providing multiple JSON samples produces better types.

Null values: null tells you the field exists but the type is ambiguous. The generator might type it as null (useless) or any (defeats the purpose). You usually need to manually specify the actual type.

Empty arrays: [] gives no information about the element type. The generator typically produces any[] or unknown[]. Fill the array with at least one example element before generating.

Union types: an array containing both strings and numbers produces (string | number)[]. An object field that is sometimes a string and sometimes an object produces a union type.

Date strings: JSON has no date type. Date values are strings that happen to contain ISO 8601 dates. Most generators type these as string, which is technically correct but not helpful. Consider using a custom type alias like type ISODateString = string for documentation.

Number ambiguity: JSON does not distinguish between integers and floats. Both are number in TypeScript. If the distinction matters to your application, add manual refinement after generation.

Format your JSON with the JSON Formatter before generating types. Properly indented JSON makes it easier to verify the generated types match the data structure.

Key takeaway

Real-world JSON is messier than textbook examples.

* * *

Popular TypeScript Type Generation Tools

quicktype (quicktype.io): the most feature-rich option. Supports JSON, JSON Schema, and GraphQL as input. Generates TypeScript, but also Python, Go, Java, and more. Handles union types, optional fields, and naming conventions. Available as a CLI tool (npm install -g quicktype) and a web interface.

json-to-ts (VS Code extension): paste JSON directly in VS Code and generate types inline. Convenient for quick one-off conversions during development.

json2ts.com: simple web tool. Paste JSON, get TypeScript. No frills, no configuration. Good for quick conversions when you do not need advanced features.

transform.tools: web-based converter that handles JSON to TypeScript among many other format conversions. Clean interface with real-time preview.

ts-json-schema-generator: works in reverse. Takes your TypeScript types and generates JSON Schema. Useful for API validation where the TypeScript types are the source of truth.

For most developers, quicktype is the best choice because it handles edge cases better than simpler tools and can be integrated into build pipelines via its CLI. For quick one-off conversions, any of the web tools work fine.

* * *

Runtime Validation: Types Are Not Enough

TypeScript types exist only at compile time. At runtime, the JSON from an API can be anything. If the API changes its response format, your TypeScript types will not catch it. Your code will fail at runtime with confusing errors.

Runtime validation libraries bridge this gap:

Zod: define a schema that both validates at runtime and infers TypeScript types at compile time. One source of truth for both.

`typescript import { z } from 'zod';

const UserSchema = z.object({ id: z.number(), name: z.string(), email: z.string().email(), role: z.enum(['admin', 'user', 'guest']) });

type User = z.infer;

// Runtime validation const user = UserSchema.parse(apiResponse); `

io-ts: similar concept using functional programming patterns. More verbose than Zod but composable.

Valibot: newer alternative to Zod with a smaller bundle size. The API is similar but tree-shakeable.

The workflow: generate initial TypeScript types from JSON, convert them to Zod schemas for runtime validation, and use z.infer to derive the TypeScript types. This gives you both compile-time and runtime safety.

Run the generated definitions through the JSON Formatter when you need to format the sample data alongside the types, so both stay consistent in your docs.

Developer working on API integration code
Developer working on API integration code
* * *

Automating Type Generation in Your Build Pipeline

For APIs you consume regularly, manual type generation does not scale. Automate it:

From OpenAPI/Swagger specs: tools like openapi-typescript read an API's OpenAPI spec and generate TypeScript types for every endpoint, request body, and response. This is the gold standard because the spec is the source of truth.

`bash npx openapi-typescript https://api.example.com/openapi.json -o src/types/api.ts `

From JSON samples: save representative API responses as fixture files. Run quicktype against them in your CI pipeline to regenerate types when the fixtures change.

From GraphQL schemas: GraphQL introspection provides a complete type system. Tools like graphql-codegen generate TypeScript types and even typed query hooks for React.

Contract testing: use tools like Pact or Dredd to verify that the actual API responses match your generated types. If the API changes, the tests fail before your production code does.

The key principle: types should be generated, not hand-written, whenever a machine-readable schema or representative sample exists. Hand-written types are for your own data models. Generated types are for external data.

When you do hand-write types, use descriptive names and JSDoc comments. A type called ApiResponseV2 with no documentation is barely better than any for the next developer who reads your code.

* * *

FAQ

Should I use `interface` or `type` for generated JSON types?

Both work. interface is slightly better for object shapes because it supports declaration merging and provides clearer error messages. type is necessary for union types and mapped types. Most generators use interface for objects and type for unions, which is a reasonable default.

How do I handle API responses that return different shapes based on status code?

Use discriminated unions. Create separate types for success and error responses, then combine them: `typescript type ApiResponse = SuccessResponse | ErrorResponse; ` Use a shared field (like status or success) as the discriminant for type narrowing in your code.

Can I generate types from a database schema?

Yes. Tools like Prisma, Drizzle, and Kysely generate TypeScript types from your database schema. Supabase also generates types from your PostgreSQL tables using supabase gen types typescript. This ensures your application types match your database exactly.

What about deeply nested JSON with many levels?

Generators handle nesting fine technically, but the resulting types can be hard to read with 5+ levels of nesting. Consider flattening deeply nested types into separate named interfaces and using composition. This improves readability and reusability.

Key takeaway

### Should I use `interface` or `type` for generated JSON types.