โ† Home ยท Blog

Generate TypeScript Types from JSON

Published: October 7, 2026 ยท 9 min read ยท By JSON Suite Team

Working with JSON APIs in TypeScript? You need types. Writing them manually is tedious and error-prone. This guide shows you how to generate TypeScript interfaces from JSON automatically, plus best practices for maintaining type safety.

Why Generate Types from JSON?

  • Type safety โ€” Catch errors at compile time, not runtime
  • Autocomplete โ€” IDE suggestions for all API fields
  • Documentation โ€” Types document your API contract
  • Refactoring โ€” Safely rename properties across codebase
  • Speed โ€” Don't manually write interfaces for complex APIs

Example: API Response to TypeScript

Given this JSON response from a user API:

{ "id": 12345, "name": "John Doe", "email": "john@example.com", "isActive": true, "roles": ["admin", "user"], "profile": { "avatar": "https://example.com/avatar.png", "bio": "Software developer", "social": { "twitter": "@johndoe", "github": "johndoe" } }, "createdAt": "2024-01-15T10:30:00Z", "lastLogin": null }

The generated TypeScript interfaces:

interface Social { twitter: string; github: string; } interface Profile { avatar: string; bio: string; social: Social; } interface User { id: number; name: string; email: string; isActive: boolean; roles: string[]; profile: Profile; createdAt: string; lastLogin: string | null; }

Type Inference Rules

When converting JSON to TypeScript, these rules apply:

JSON ValueTypeScript Type
"hello"string
42, 3.14number
true, falseboolean
nullnull
[1, 2, 3]number[]
["a", "b"]string[]
[1, "a", true](number | string | boolean)[]
{...}interface (nested)
[{...}, {...}]Interface[]

Interface vs Type Alias

TypeScript offers two ways to define object types:

// Interface (preferred for objects) interface User { id: number; name: string; } // Type alias (preferred for unions, primitives) type UserRole = "admin" | "user" | "guest"; type MaybeUser = User | null; // Interfaces can be extended interface AdminUser extends User { permissions: string[]; } // Types can use intersection type AdminUser = User & { permissions: string[] };

Recommendation: Use interfaces for object shapes (they're more extendable), use type aliases for unions and primitives.

Handling Optional Fields

APIs often have optional fields. Mark them with ?:

interface User { id: number; name: string; email: string; phone?: string; // Optional field avatar?: string | null; // Optional and nullable } // Usage const user: User = { id: 1, name: "John", email: "john@example.com" // phone and avatar can be omitted };

Handling Dates

JSON doesn't have a date type. Dates come as strings:

// JSON { "createdAt": "2024-01-15T10:30:00Z" } // Option 1: Keep as string interface Event { createdAt: string; // ISO 8601 string } // Option 2: Parse to Date in runtime interface Event { createdAt: Date; } // Runtime conversion const event: Event = { ...json, createdAt: new Date(json.createdAt) }; // Option 3: Use a library like date-fns or dayjs import { parseISO } from 'date-fns'; const date = parseISO(json.createdAt);

Arrays with Multiple Object Types

When an array contains different object structures:

// JSON with mixed array { "items": [ { "type": "text", "content": "Hello" }, { "type": "image", "url": "pic.png", "width": 100 } ] } // TypeScript discriminated union interface TextItem { type: "text"; content: string; } interface ImageItem { type: "image"; url: string; width: number; } type Item = TextItem | ImageItem; interface Response { items: Item[]; } // Type-safe usage response.items.forEach(item => { if (item.type === "text") { console.log(item.content); // TypeScript knows this exists } else { console.log(item.url); // TypeScript knows this exists } });

Using Generics for API Responses

Wrap your types in a generic API response:

// Generic API response wrapper interface ApiResponse<T> { data: T; status: "success" | "error"; message?: string; timestamp: string; } // Usage type UserResponse = ApiResponse<User>; type UsersListResponse = ApiResponse<User[]>; // Fetch with type safety async function fetchUser(id: number): Promise<ApiResponse<User>> { const response = await fetch(`/api/users/${id}`); return response.json(); } const result = await fetchUser(123); if (result.status === "success") { console.log(result.data.name); // Full autocomplete! }

Runtime Validation

TypeScript types only exist at compile time. For runtime validation, use libraries:

// Using Zod for runtime validation import { z } from 'zod'; const UserSchema = z.object({ id: z.number(), name: z.string(), email: z.string().email(), roles: z.array(z.string()), }); // Infer TypeScript type from Zod schema type User = z.infer<typeof UserSchema>; // Runtime validation const result = UserSchema.safeParse(jsonData); if (result.success) { const user: User = result.data; // Type-safe! } else { console.error(result.error); }

Best Practices

  1. Use readonly for immutable data
    interface User { readonly id: number; // Can't be modified name: string; }
  2. Prefer explicit types over 'any'
    // Bad const data: any = await fetch(...); // Good const data: User = await fetch(...).then(r => r.json());
  3. Use 'unknown' for truly unknown data
    function parseJSON(text: string): unknown { return JSON.parse(text); } // Forces type checking before use
  4. Group related types in modules
    // types/user.ts export interface User { ... } export interface UserProfile { ... } export type UserRole = "admin" | "user";

Tools for Generating Types

  • JSON Suite TypeScript Generator โ€” Paste JSON, get interfaces instantly
  • quicktype โ€” CLI tool for multiple languages
  • json2ts โ€” VS Code extension
  • OpenAPI Generator โ€” Generate from API specs

Workflow for API Integration

  1. Fetch a sample API response
  2. Paste into JSON to TypeScript converter
  3. Review and adjust generated types (optional fields, unions)
  4. Save to your types/ folder
  5. Import and use with full type safety

Try It Yourself

Ready to convert your JSON to TypeScript? Use our free JSON to TypeScript Converter. Paste any JSON and get properly typed interfaces instantly โ€” including nested objects, arrays, and nullable fields.

For generating code in other languages, check out our JSON to Code generator supporting Python, Go, Java, C#, and more.

Related Tools

Generate types and work with JSON:

More Articles

What is JSON โ€” A Complete Guide

Parse JSON in JavaScript

JSON API Best Practices

JSON Schema Explained