JSON-Typen-Generator
Generieren Sie TypeScript, Python Dataclass, Go Struct und PHP DTO Definitionen aus JSON
Generating TypeScript Interfaces from JSON: Automated Type Inference
Working with external APIs, configuration files, or mock data in TypeScript projects means writing type definitions that match the actual shape of your data. Manually creating interfaces for deeply nested JSON responses is tedious, error-prone, and rarely kept in sync as APIs evolve. This tool analyzes JSON sample data and automatically generates accurate TypeScript interfaces, Python dataclasses, Go structs, and PHP classes — giving you type-safe code in seconds instead of minutes of manual transcription. The generated types catch property access errors at compile time, enable IDE autocompletion, and serve as living documentation for your data contracts.
Type Inference Strategies: From Values to Types
Converting JSON values into static types requires inferring the narrowest accurate type from
sample data. The inference engine applies several strategies to produce useful types rather
than overly broad any annotations:
- Primitive mapping: JSON strings become
string, numbers becomenumber, booleans becomeboolean, andnullbecomesnull. This direct mapping covers the majority of leaf values. - Array element unification: When an array contains objects with different shapes, the engine computes the union of all property sets. Properties present in every element are required; properties missing from at least one element become optional with the
?modifier. - Null handling: A value of
nullin the sample signals that the property accepts null. The generated type uses a union:string | nullrather than marking the property as optional, preserving the semantic difference between "absent" and "explicitly null." - Nested object extraction: Objects nested within the root structure are extracted into separate named interfaces. A property
addresscontaining an object generates anAddressinterface and references it by name, improving readability over inline type literals. - Mixed-type arrays: Arrays containing elements of different primitive types generate tuple types or union arrays depending on the pattern. An array like
[1, "two", true]produces(number | string | boolean)[]rather thanany[].
These strategies prioritize developer ergonomics — the resulting types should be as specific
as the sample data allows without being so narrow that slight API changes break compilation.
When in doubt, the engine favors union types over any, preserving type safety
while accommodating reasonable variation.
Handling Ambiguous Types and Edge Cases
Real-world JSON data frequently contains patterns that complicate type inference. The converter addresses these edge cases with deliberate strategies:
- Optional vs. nullable: A property present with value
nullgeneratesproperty: string | null. A property entirely missing from some array elements generatesproperty?: string. Both patterns coexist:property?: string | nullmeans "may be absent, and when present, may be null." - Empty arrays: An empty array
[]provides no element samples, so the engine defaults tounknown[]in TypeScript orList[Any]in Python. Providing arrays with at least one element yields more precise types. - Numeric ambiguity: JSON has a single number type, but target languages distinguish integers from floats. The converter inspects whether all sample numbers lack decimal portions — if so, it generates
intin Go/Python/PHP. Otherwise, it usesfloat64,float, orfloatrespectively. - Date-like strings: Strings matching ISO 8601 patterns (e.g.,
"2024-03-15T10:30:00Z") are annotated with a comment suggestingDatetype usage, though they remain typed asstringsince JSON has no native date type. - Deeply nested structures: Objects nested beyond three levels generate flattened interface names using parent context:
UserAddressCoordinatesrather than genericCoordinates, avoiding naming collisions across unrelated nested objects.
The key principle is that generated types should compile without errors against the sample data while remaining flexible enough to handle reasonable variations in production API responses.
Multi-Target Output: TypeScript, Python, Go, and PHP
While TypeScript interfaces are the primary output, the same JSON structure maps naturally to type systems in other languages. Each target applies language-specific conventions:
- TypeScript interfaces: Uses
interfacedeclarations with optional properties (?), union types (|), andreadonlyarrays. Naming follows PascalCase for interfaces and camelCase for properties — matching the TypeScript Handbook conventions. - Python dataclasses: Generates
@dataclassclasses with type annotations from thetypingmodule (Optional,List,Union). Also supportsTypedDictoutput for scenarios requiring dictionary-style access rather than attribute access. - Go structs: Produces struct definitions with exported field names in PascalCase and
json:"field_name"struct tags for proper serialization. Pointer types (*string) represent nullable fields, andomitemptytags mark optional properties. - PHP classes: Generates classes with typed properties (PHP 7.4+), nullable type declarations (
?string), and constructor promotion (PHP 8.0+). Property names follow camelCase, and arrays use PHPDoc@varannotations for element typing since PHP lacks generics.
Each output format handles the same structural information — property names, types, optionality, and nesting — but expresses it through the idioms developers expect in that language ecosystem. This makes the generated code immediately usable without manual adaptation.
Naming Conventions and Nested Object Handling
Interface naming significantly impacts code readability. The converter applies these rules to produce clean, idiomatic names from JSON property keys:
- Root interface: Named
RootObjectby default, or derived from context if the JSON originates from a named API endpoint. Users can customize the root name before generating. - Nested objects: Named after their parent property key converted to PascalCase. A property
"shipping_address"containing an object generatesinterface ShippingAddress. - Array elements: When an array property like
"items"contains objects, the element interface is named using the singular form:Item. Common plural-to-singular transformations (removing trailing "s", "es", or "ies→y") are applied heuristically. - Collision avoidance: If two nested objects at different paths would produce the same interface name, the parent path is prepended:
OrderItemvsCartIteminstead of two conflictingIteminterfaces. - Property key preservation: While interface names are transformed to PascalCase, property names within interfaces preserve the original JSON casing. This ensures
JSON.parse()results map directly to the interface without a transformation layer.
For Go output, struct field names are converted to exported PascalCase with corresponding
json struct tags maintaining the original key. For Python, snake_case conversion
is applied to property names following PEP 8, with the original JSON key preserved in
dataclass field metadata for serialization.
Practical Use Cases: API Responses, Config Files, and Mock Data
Generating types from JSON accelerates development across several common workflows:
- API response typing: Paste a sample response from your REST API, generate the interface, and immediately get autocompletion and error checking when accessing response properties. This eliminates "property does not exist on type" errors caught late in development.
- Configuration file typing: Application configs stored as JSON (database connections, feature flags, environment-specific settings) benefit from typed access. The generated interface catches typos in config property names at compile time.
- Mock data contracts: When frontend and backend teams agree on an API shape before implementation, generating types from the agreed JSON schema ensures both teams work against the same contract. Changes to the mock data regenerate types and immediately surface breaking changes.
- Database document typing: NoSQL databases (MongoDB, DynamoDB, Firestore) store documents as JSON-like structures. Generating types from sample documents provides type safety for queries and mutations without an ORM layer.
- Third-party API integration: When an external API lacks official TypeScript definitions, a single sample response generates usable types immediately — far faster than manually reading API documentation and transcribing property names and types.
In each case, the generated types serve as a starting point. Developers can refine them — narrowing string literals, adding branded types, or introducing generic parameters — while the auto-generated version handles the repetitive structural mapping that no human enjoys writing by hand.
Code Examples
JSON API response to TypeScript interface
{
"id": 1042,
"name": "Jane Doe",
"email": "jane@example.com",
"is_active": true,
"role": "admin",
"address": {
"street": "123 Main St",
"city": "Portland",
"state": "OR",
"zip": "97201"
},
"tags": ["developer", "team-lead"],
"last_login": null
}Output:
interface RootObject {
id: number;
name: string;
email: string;
is_active: boolean;
role: string;
address: Address;
tags: string[];
last_login: string | null;
}
interface Address {
street: string;
city: string;
state: string;
zip: string;
}Generated Go struct with JSON tags
type RootObject struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
IsActive bool `json:"is_active"`
Role string `json:"role"`
Address Address `json:"address"`
Tags []string `json:"tags"`
LastLogin *string `json:"last_login"`
}
type Address struct {
Street string `json:"street"`
City string `json:"city"`
State string `json:"state"`
Zip string `json:"zip"`
}Standards & Specifications
- TypeScript Handbook — Object Types — Official TypeScript documentation on interface declarations, optional properties, and index signatures
- RFC 8259 (JSON) — The JSON data interchange format specification — defines the input format this tool parses
- JSON Schema — Schema vocabulary for annotating and validating JSON documents — complementary approach to type generation