JSON to TypeScript — Free Online Tool
Convert JSON to TypeScript: generate interfaces, types, enums. Infer types from JSON, handle arrays, nested objects, optional fields. Online JSON to TS converter.
Use this free online JSON to TypeScript directly in your browser. No signup required, no data leaves your device. Part of Utilier — a collection of 133+ developer utilities.
What is JSON to TypeScript Interface/Type Generator (Online Converter)?
JSON to TypeScript converter generates TypeScript interfaces, types, or type aliases from JSON data. Analyzes: JSON structure (objects, arrays, primitives), infers types (string, number, boolean, null), generates TS code (interface User {id: number; name: string;}). Handles: nested objects (address: {city: string; zip: number}), arrays (tags: string[], users: User[]), optional fields (email?: string when missing in some objects), unions (id: string | number when mixed types), enums (status: 'active' | 'inactive'). Features: batch conversion (multiple JSON objects → detect common shape), naming (auto-generates interface names: User, Address), export (copy TS code), customization (interface vs type, optional handling). Use cases: API integration (response → TS types), mock data → types (Faker.js output), documentation (JSON schema → TS interfaces).
- Type inference: Analyzes JSON values → determines TS types. "name": "John" → name: string. "age": 30 → age: number. "active": true → active: boolean. null → null or any. Arrays → type[] (strings: string[], mixed: (string | number)[]).
- Interface generation: JSON object → TS interface. {"id": 1, "name": "John"} → interface Root {id: number; name: string;}. Nested: {"user": {"id": 1}} → interface User {id: number;} interface Root {user: User;}. Reusable types.
- Array handling: Array of primitives: ["a", "b"] → string[]. Array of objects: [{"id": 1}, {"id": 2}] → interface Item {id: number;} type Root = Item[]; Detects item type (all objects same shape).
- Optional fields: Field missing in some objects: [{"id": 1, "email": "a@b.com"}, {"id": 2}] → interface Item {id: number; email?: string;} (email optional: ?). Not all objects have it.
- Union types: Mixed types: {"id": "a"}, {"id": 1} → id: string | number (union). Or {"status": "active"}, {"status": "inactive"} → status: 'active' | 'inactive' (string literal union, enum-like).
Why use json to typescript?
Skip manual typing (error-prone). Generate accurate types from real API data.
- API integration (type safety): API response: {"id": 1, "name": "Product", "price": 99.99}. Generate: interface Product {id: number; name: string; price: number;}. Use in fetch: const data: Product = await response.json(). TypeScript checks: accessing data.price (valid), data.quantity (error: doesn't exist).
- Avoid manual type errors: Manual typing: interface User {id: number; name: string; email: number;} (email should be string, typo). JSON converter: sees "email": "a@b.com" → email: string (correct type inferred). No typos.
- Handle complex nested structures: API: {"user": {"profile": {"address": {"city": "NYC"}}}}. Manual: 4 nested interfaces (User, Profile, Address, City). Converter: generates all automatically with correct nesting. Faster.
- Consistency with API: API changes: adds new field 'createdAt'. Re-convert JSON → new type includes createdAt. Manual types: easy to forget updating. Converter: always matches latest API response shape.
- Documentation: API docs show example JSON response. Generate TS types → developers know exact shape. Example: interface ApiResponse {status: string; data: User[]; error?: string;} (clear structure, optional error).
- Mock data to types: Faker.js/JSON mock data for tests. Generate types from mocks → use in test files. Example: const mockUser: User = {id: 1, name: 'Test'}; (type ensures mock matches real shape).
When to use json to typescript
Use when working with JSON data in TypeScript projects.
- Integrating third-party APIs (convert response JSON to TS types).
- Creating types for config files (package.json, tsconfig.json).
- Generating types from API documentation examples.
- Converting mock/test data to types (Faker.js, fixtures).
- Refactoring JavaScript to TypeScript (existing JSON → types).
- Prototyping (quickly create types from sample data).
- Code generation (JSON schema → TypeScript interfaces).
- Ensuring type safety (JSON data → typed variables).
How to use json to typescript
Paste JSON, generate TypeScript interfaces or types, copy result.
- Paste JSON data: Enter JSON: {"id": 1, "name": "John", "email": "john@example.com"}. Or array: [{"id": 1}, {"id": 2}]. Or nested: {"user": {"profile": {...}}}. Any valid JSON.
- Choose output format: Select: Interface (interface User {...}), Type (type User = {...}), or Inline type (const user: {id: number; name: string} = ...). Interface: reusable, extendable. Type: aliases, unions.
- Configure options: Root name: 'User' (interface User {...}), 'ApiResponse', etc. Optional handling: always optional (?), or only if missing in sample. Array handling: Item[] vs Array<Item>. Prefix/suffix: IUser, UserType.
- Generate TypeScript: Click Generate. Output: interface User {id: number; name: string; email: string;}. Nested: interface Profile {...} interface User {profile: Profile;}. Copy code.
- Refine if needed: Review: types correct? Example: 'id' inferred as number, but API uses string IDs → change id: number to id: string. Or add readonly: readonly id: number (immutable). Edit manually.
- Use in project: Paste in types.ts or api.ts. Import: import {User} from './types'. Use: const user: User = await fetchUser(); (type safety). TypeScript validates usage.
- Handle edge cases: null values: inferred as null or any (specify: id: number | null). Empty arrays: [] → any[] (provide sample with items). Mixed types: ["a", 1] → (string | number)[].
Key features
- Automatic type inference: Detects: string ("text"), number (123, 45.67), boolean (true, false), null, arrays ([...]), objects ({...}). Generates: name: string, age: number, active: boolean, tags: string[], data: null.
- Nested object support: JSON: {"user": {"address": {"city": "NYC"}}}. Output: interface Address {city: string;} interface User {address: Address;} interface Root {user: User;}. Separate interfaces (reusable).
- Array type detection: Primitives: ["a", "b"] → string[]. Objects: [{"id": 1}] → Item[]. Mixed: ["a", 1] → (string | number)[]. Empty: [] → any[] (or specify: never[]). Consistent item types → single type.
- Optional field detection: Multiple objects: [{"id": 1, "email": "a@b.com"}, {"id": 2}] (email missing in 2nd). Output: id: number; email?: string; (email optional). Analyzes all samples.
- Union type generation: Mixed types: {"id": "a"}, {"id": 1} → id: string | number. String literals: {"status": "active"}, {"status": "inactive"} → status: 'active' | 'inactive'. Enum-like behavior.
- Interface vs Type: Choose output: interface User {...} (extendable, declaration merging) or type User = {...} (aliases, unions, intersections). Interface: classes, objects. Type: complex unions.
- Customization options: Root name (User, ApiResponse). Prefix/suffix (IUser, UserType). Optional handling (always, never, auto). Array syntax (T[] vs Array<T>). Export keyword (export interface). Readonly fields.
Common use cases
- API response typing: Fetch API: const res = await fetch('/api/users'); const data = await res.json(); (data: any). Generate: interface User {id: number; name: string; email: string;} from sample response. Use: const data: User[] = await res.json(); (typed).
- GraphQL to TypeScript: GraphQL query returns: {"user": {"id": "1", "name": "John"}}. Generate: interface User {id: string; name: string;} interface Query {user: User;}. Use with Apollo/urql: useQuery<Query>('...').
- Config file types: package.json: {"name": "app", "version": "1.0.0", "scripts": {...}}. Generate: interface PackageJson {name: string; version: string; scripts: Record<string, string>;}. Use: const pkg: PackageJson = require('./package.json');
- Mock data for tests: Faker.js: const user = {id: faker.number.int(), name: faker.person.fullName()}. Generate: interface MockUser {id: number; name: string;}. Use: const testUser: MockUser = {id: 1, name: 'Test'}; (typed mocks).
- JSON schema to types: OpenAPI/Swagger JSON schema: {"type": "object", "properties": {"id": {"type": "number"}}}. Convert example to TS. Or use with json-schema-to-typescript (similar tool). Generate types from specs.
- Database query results: SQL query result: [{"user_id": 1, "user_name": "John"}]. Generate: interface QueryResult {user_id: number; user_name: string;}. Or rename: interface User {userId: number; userName: string;} (camelCase).
Examples
Common JSON to TypeScript conversion examples.
Simple object
{"id": 1, "name": "John", "active": true}interface Root { id: number; name: string; active: boolean;
}Primitive types inferred: number, string, boolean. Root interface name (configurable).
Nested objects
{"user": {"id": 1, "profile": {"bio": "Developer"}}}interface Profile { bio: string;
}
interface User { id: number; profile: Profile;
}
interface Root { user: User;
}Nested objects → separate interfaces. Reusable types (User, Profile). Root contains user.
Array of objects
[{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]interface Item { id: number; name: string;
}
type Root = Item[];Array of objects → Item interface + array type. All items same shape (id, name).
Optional fields
[{"id": 1, "email": "a@b.com"}, {"id": 2}]interface Item { id: number; email?: string;
}
type Root = Item[];email present in 1st object, missing in 2nd → optional (?). id always present (required).
Union types
{"status": "active"}, {"status": "inactive"}interface Root { status: 'active' | 'inactive';
}String literal values → union type (enum-like). Or status: string (wider type, less specific).
Technical reference
JSON to TypeScript conversion rules and type mappings:
- Primitive types
- JSON string → TS string. JSON number → TS number (int and float both number). JSON boolean → TS boolean. JSON null → TS null (or any, depending on option). Exact mapping.
- Objects
- JSON object → TS interface or type. {"a": 1, "b": "x"} → interface Root {a: number; b: string;}. Keys become properties. Nested objects → nested interfaces (or inline types).
- Arrays
- Homogeneous: [1, 2, 3] → number[]. Objects: [{"id": 1}] → Item[]. Mixed: ["a", 1] → (string | number)[]. Empty: [] → any[] (can't infer type). Tuple: [1, "a"] → [number, string] (if strict).
- Optional fields
- Field present in some objects, missing in others → optional (?). Example: {"id": 1, "email": "a@b.com"}, {"id": 2} → email?: string. Detected by analyzing multiple samples.
- Union types
- Mixed types in same field → union. {"id": 1}, {"id": "a"} → id: string | number. String literals: "active", "inactive" → status: 'active' | 'inactive' (literal union). Or status: string (wider type).
- null vs undefined
- JSON null → TS null. JSON undefined: doesn't exist (JSON doesn't support undefined). Missing field → optional (?) or undefined (--strictNullChecks). null in JSON: id: number | null (explicit).
- any vs unknown
- Can't infer type (null, empty array, mixed complex) → any (permissive) or unknown (strict, requires type checking). unknown safer (must narrow type before use). Option to prefer unknown over any.
- Date handling
- JSON doesn't have Date type (strings: "2024-01-15T10:00:00Z"). Inferred as string. Manual: change to Date or custom type (ISOString). Or use library (class-transformer: @Type(() => Date)).
- Interface naming
- Root object: Root, RootObject, or custom (User, ApiResponse). Nested: based on key (address → Address, user.profile → Profile). Arrays: singular form (users → User[]). Configurable prefix/suffix.
- Export keyword
- Option: export interface User {...} (exported, available for import) vs interface User {...} (local). Useful for library/module types. Generate with export for reuse across files.
Common mistakes to avoid
Using single sample (incomplete types)
Why it happens: API returns: {"id": 1, "name": "John"} (sample 1), sometimes: {"id": 2, "name": "Jane", "email": "jane@example.com"} (sample 2 has email). Generated from sample 1: no email field (missing type).
How to avoid it: Provide multiple samples (all variations). Or check API docs (all possible fields). Generate: id: number; name: string; email?: string; (email optional, detected from multiple samples).
Not handling null values (missing | null)
Why it happens: API: {"data": {...}} or {"data": null} (null when no data). Generated: data: DataType (no null). Using: if (response.data.id) → error when data = null (can't read id of null).
How to avoid it: Check for null in JSON. Generate: data: DataType | null. Use: if (response.data && response.data.id) (null check). Or optional: data?: DataType (undefined if missing).
Incorrect array types (any[] from empty array)
Why it happens: JSON: {"tags": []} (empty array). Generated: tags: any[] (can't infer item type). Using: tags.push(123) (valid), tags.push("text") (valid) → mixed types, no safety.
How to avoid it: Provide sample with items: {"tags": ["tag1", "tag2"]} → tags: string[]. Or specify manually: tags: string[] (expected type). Empty array = no inference.
Missing Date types (dates as strings)
Why it happens: API: {"createdAt": "2024-01-15T10:00:00Z"} (ISO string). Generated: createdAt: string. Using: createdAt.getFullYear() (error: string has no getFullYear method).
How to avoid it: Manually change: createdAt: Date (or ISOString custom type). Or use transformer: new Date(data.createdAt). JSON doesn't have Date (always strings), must convert manually.
Not using generated types (still using any)
Why it happens: Generated: interface User {id: number; name: string;}. Code: const data: any = await res.json(); (not using User type). No type checking (data.nam typo = no error, runtime failure).
How to avoid it: Use generated type: const data: User = await res.json(); TypeScript checks: data.name (valid), data.nam (error: property doesn't exist). Catch typos at compile time.
Frequently asked questions
What's the difference between interface and type in the output?
Interface: extendable (interface User extends Base {...}), declaration merging (multiple interface User {...} combine). Type: aliases, unions (type ID = string | number), intersections (type A = B & C). Use interface for objects, type for complex types.
How does the tool handle optional fields?
Analyzes multiple objects: if field present in some, missing in others → optional (?). Example: [{"id": 1, "email": "a@b.com"}, {"id": 2}] → email?: string. Or configure: always optional, or required (manual editing needed).
Can I convert an array of different object shapes?
Yes. [{"id": 1}, {"name": "John"}] → union type: type Item = {id: number} | {name: string}. Or common fields: {id?: number; name?: string} (all optional). Mixed shapes = union or optional fields.
How do I handle dates in JSON?
JSON has no Date type (uses strings: "2024-01-15T10:00:00Z"). Tool infers: createdAt: string. Manually change to: Date, or custom (type ISOString = string). Or transform: new Date(data.createdAt) when parsing.
Can I customize interface names?
Yes. Root name: Root, RootObject, User, ApiResponse (configurable). Nested: based on key (user → User, address → Address). Prefix/suffix: IUser, UserType, UserInterface. Or edit generated code manually.
What about empty arrays ([]) in JSON?
Empty array → any[] (can't infer item type). No items to analyze. Provide sample with items: [1, 2] → number[], [{"id": 1}] → Item[]. Or manually specify: string[], User[] (expected type).
How do I handle union types (mixed types in same field)?
Mixed values: {"id": "a"}, {"id": 1} → id: string | number (union). Or literals: "active", "inactive" → status: 'active' | 'inactive'. Use unions for flexible types (narrow with type guards: typeof id === 'string').
References
Privacy and availability
- Runs entirely in your browser — zero server processing
- No signup or account required
- Works offline once loaded
- Fast, lightweight, no external dependencies
- Available as a browser extension for Chrome and Firefox