Skip to content

A powerful tool that automatically generates TypeScript interfaces from JSON objects, making type-safe development easier and more efficient.

Notifications You must be signed in to change notification settings

blacksmoke26/json2ts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

JSON to TypeScript Interface Converter

A powerful tool that automatically generates TypeScript interfaces from JSON objects, making type-safe development easier and more efficient.

Features ✨

  • πŸ”§ Convert JSON to TypeScript interfaces with ease
  • πŸ“¦ Generate separate interfaces for nested objects
  • πŸ”’ Intelligent type inference for Numbers, Strings, Booleans, and null values
  • πŸ“‹ Create type definitions for arrays, objects and primitive types
  • πŸ”„ Transform nested/complex JSON into flattened interface via --flat flag
  • ✏️ Specify custom names for root interfaces
  • πŸ—‚οΈ Preserve original JSON structure in generated interfaces
  • 🌐 Export options for generated interfaces (all, root, none)
  • πŸ“Š Handle complex nested structures with arrays of objects
  • πŸš€ Fast and lightweight CLI for quick conversions
  • πŸ“ Support for both file and direct text input
  • πŸ”Œ Read JSON output directly from the stdin for pipeline operations
  • ✏️ Added property name suggestion and correction logic based on strict TypeScript identifier rules
  • πŸ”„ Automatically detects and resolves circular references in JSON structures to prevent infinite recursion
  • πŸ›‘οΈ Generate strict TypeScript types with exact property matching when enabled via --strict flag
  • πŸ”’ Read-only Properties: Generate immutable interfaces with readonly modifier
  • ❓ Optional Properties: Generate interfaces with all properties marked optional (?)
  • πŸͺ Property Case Transformation: Convert property names to various case formats:
    • c - camelCase (userName)
    • l - lower_snake_case (user_name)
    • o - preserve original (default)
    • p - PascalCase (UserName)
    • u - UPPER_SNAKE_CASE (USER_NAME)
    • k - kebab-case (user-name)
  • πŸ“ Smart Array Type Detection: Automatically infers array types including:
    • Primitive arrays (e.g., string[], number[])
    • Mixed-type tuples (e.g., [string, number, boolean])
    • Object arrays (e.g., User[])
    • Nested arrays with proper type preservation
  • πŸ—ΊοΈ Custom Type Mapping: Override default type detection with custom mappings:
    • Map specific JSON properties to custom TypeScript types
    • Useful for integrating with existing type definitions
    • Example: Map "user_id" to UserID type
    • Configure via typeMap option in API or CLI

Command Line Interface πŸ’»

The package includes a command-line interface (CLI) for quick conversions without writing code.

Installation πŸ“¦

npm install -g @junaidatari/json2ts # NPM pnpm install -g @junaidatari/json2ts # PNPM yarn global add @junaidatari/json2ts # Yarn

Command Options βš™οΈ

Option Type Description Default
-f, --file string Path to JSON file to convert Required*
-t, --text string Raw JSON string to convert Required*
-o, --output string Output file path Prints to console
-n, --name string Root interface name RootObject
-l, --flat boolean Generate flattened interface -
-e, --export string Export type: a=all, r=root, n=none r (root)
--pc, --property-case string Property case transformation: c=camelCase, l=lower_snake, o=original, p=PascalCase, u=UPPER_SNAKE, k=kebab-case o (original)
-s, --strict boolean Generate strict TypeScript types with exact property matching -
-r, --readonly boolean Make all generated properties readonly -
--op, --optional boolean Make all generated properties optional -

Either --file or --text must be provided or pipe through to read directly from the stdin.

Examples πŸ“

Basic file conversion

json2ts -f input.json -o types.ts -n ApiResponse

Direct text conversion

# Linux/Mac json2ts -t '{"user": {"name": "John"}}' -n User # Windows json2ts -t "{\"user\": {\"name\": \"John\"}}" -n User

Readonly properties

# Generate with readonly properties json2ts -f input.json -o readonly-types.ts -n Data --readonly # Combine with strict mode json2ts -f input.json -o strict-readonly.ts -n Data --strict --readonly

Optional properties

# Generate with optional properties json2ts -f input.json -o optional-types.ts -n Data --op # Combine with readonly mode json2ts -f input.json -o readonly-optional.ts -n Data --readonly --optional

Generate flattened interface

json2ts -f complex.json -o flat-types.ts -n Data --flat

Export all interfaces

json2ts -f input.json -o types.ts -n Response -e a

No exports (internal interfaces)

json2ts -f input.json -o types.ts -n Response --export n

Property case transformation

# Convert to camelCase properties json2ts -f input.json -o camel-types.ts --pc c # Convert to PascalCase properties json2ts -f input.json -o pascal-types.ts --property-case p # Convert to kebab-case properties json2ts -f input.json -o kebab-types.ts --property-case k

Strict mode generation

# Generate with strict type checking json2ts -f input.json -o strict-types.ts -n Data --strict

Combined options

# Multiple options together json2ts -f input.json -o output.ts -n ApiResponse -e a --property-case c --strict # Flattened with property transformation json2ts -f data.json -o flat.ts -n FlatData --flat --property-case l

Root-only export

# Export only root interface (default) json2ts -f input.json -o types.ts -n Response # or explicitly json2ts -f input.json -o types.ts -n Response -e r

Pipeline with curl

curl -s https://jsonplaceholder.typicode.com/posts/1 | \ json2ts -n UserResponse -o user-types.ts

Pipeline with other commands

# Convert from clipboard (Linux) xclip -selection clipboard -o | json2ts -n ClipboardData # Convert from file and copy to clipboard json2ts -f data.json | tee types.ts | pbcopy # Format with prettier curl -s https://api.example.com/data | json2ts -n Data | \ npx prettier --parser typescript

Configuration files

# Convert package.json cat package.json | json2ts -n PackageConfig -o package-types.ts # Convert tsconfig.json json2ts -f tsconfig.json -n TsConfig -o tsconfig-types.ts

Database exports

# MongoDB export mongoexport --collection users --out users.json json2ts -f users.json -n UserDoc -o user-types.ts --export a # PostgreSQL query psql -c "SELECT row_to_json(t) FROM (SELECT * FROM users) t" | \ json2ts -n DBUser -o db-types.ts

Interactive usage

echo '{"name": "test", "data": {"items": [1, 2, 3]}}' | \ json2ts -n TestData json2ts -n Config -o config-types.ts << EOF {  "server": {"port": 3000},  "database": {"url": "mongodb://localhost"} } EOF

Development workflows

# Generate types from API schema curl -s "$API_SCHEMA_URL" | json2ts -n Schema -o src/types/api.ts # Watch for changes while inotifywait -e modify data/; do for file in data/*.json; do base=$(basename "$file" .json) json2ts -f "$file" -o "types/${base}.ts" -n "${base^}Type" done done # Process all JSON files find src/data -name "*.json" -exec sh -c \ 'json2ts -f "$0" -o "src/types/$(basename "$0" .json).ts"' {} \;

Multiple files script

for file in data/*.json; do base=$(basename "$file" .json) json2ts -f "$file" -o "types/${base}.ts" -n "${base^}Data" done

Real-world API integration

# GitHub API: Get repository information curl -s https://api.github.com/repos/torvalds/linux | \ json2ts -n GithubRepo -o repo-types.ts --property-case c # Reddit API: Fetch subreddit posts curl -s -H "User-Agent: json2ts" \ "https://www.reddit.com/r/typescript/top.json?limit=10" | \ json2ts -n RedditPost -o reddit-types.ts --export a # GraphQL API query with curl curl -s -X POST https://api.spacex.land/graphql \ -H "Content-Type: application/json" \ -d '{"query": "{ launches { id name rocket { name } } }"}' | \ jq -r '.data.launches[0]' | \ json2ts -n SpaceXLaunch -o spacex-types.ts --property-case p

Database schema introspection

# PostgreSQL schema extraction psql -d myapp -c "  SELECT json_agg(t) FROM (  SELECT   table_name,  array_agg(column_name::text) as columns,  array_agg(data_type::text) as types  FROM information_schema.columns   WHERE table_schema = 'public'  GROUP BY table_name  ) t " | json2ts -n DBSchema -o db-schema.ts --readonly # MongoDB collection structure analysis mongo myapp --eval "  db.users.findOne().forEach(printjson) " | json2ts -n MongoUser -o mongo-types.ts --strict # Prisma schema introspection npx prisma introspect --print | \ grep -o '"model"[^}]*}' | \ json2ts -n PrismaModel -o prisma-types.ts --export a

Configuration management

# Kubernetes deployment analysis kubectl get deployment myapp -o json | \ json2ts -n K8sDeployment -o k8s-types.ts --readonly # Docker compose configuration docker compose config --format json | \ json2ts -n DockerCompose -o compose-types.ts --property-case l # Terraform state parsing terraform show -json | \ jq '.values.root_module.resources[] | select(.type == "aws_instance")' | \ json2ts -n TFInstance -o terraform-types.ts --strict

Testing and validation

# Generate test types from JSON schema jsonschema2jsonpointer schema.json | \ jq -r '.[] | .pointer' | \ xargs -I {} json2ts -f schema.json -n TestSchema --strict # Validate API responses against types for endpoint in users posts comments; do curl -s "https://api.example.com/$endpoint" | \ json2ts -n "${endpoint^}Response" -o "test/types/${endpoint}.ts" done # Generate mock data types jq -n '{  users: [range(10) | {  id: .,  name: "User\(.)",  email: "user\(.)@example.com",  roles: ["user", (\. % 3 == 0 and "admin" or empty)]  }] }' | json2ts -n MockUsers -o mock-types.ts --export a

Advanced pipeline operations

# Multi-stage transformation curl -s https://api.exchangerate-api.com/v4/latest/USD | \ jq '{rates: .rates | to_entries | map({key: .key, value: .value})}' | \ json2ts -n ExchangeRate -o rates.ts --property-case c | \ npx prettier --parser typescript > src/types/rates.ts # Parallel processing echo 'users posts comments products' | \ tr ' ' '\n' | \ xargs -P 4 -I {} bash -c "  curl -s \"https://api.example.com/{}\" | \  json2ts -n \"\$(echo {} | sed 's/.*/\u&/')\" -o \"types/{}.ts\"  " # Conditional type generation json2ts -f data.json -o temp.ts -n Data && \ if grep -q 'interface.*{' temp.ts; then echo "Generated interface:" cat temp.ts else echo "No interfaces generated" fi rm temp.ts

Enterprise workflows

# Service mesh configuration istioctl proxy-config routes deployment/reviews.default -o json | \ jq '.httpRoutes[0].route[0].match' | \ json2ts -n IstioRoute -o istio-types.ts --readonly # OpenAPI schema conversion curl -s https://petstore.swagger.io/v2/swagger.json | \ jq '.definitions' | \ json2ts -n PetStore -o api-types.ts --export a # Microservice contract generation for service in auth payment notification; do curl -s "https://contract-registry.internal/api/v1/contracts/$service" | \ jq '.schema' | \ json2ts -n "${service^}Contract" -o "src/contracts/${service}.ts" --strict done # CloudFormation template parsing aws cloudformation get-template --stack-name my-stack | \ jq -r '.TemplateBody' | \ json2ts -n CFTemplate -o cf-types.ts --property-case k

CI/CD integration

# GitHub Actions workflow validation find .github/workflows -name '*.yml' -exec \ yq eval -o json {} \; | \ json2ts -n GitHubAction -o action-types.ts # Azure DevOps pipeline analysis az pipelines show --id $(az pipelines list --query [0].id -o tsv) | \ jq '.process' | \ json2ts -n AzPipeline -o pipeline-types.ts # Dockerfile instruction parsing docker inspect $(docker build -q .) | \ jq -r '.[0].Config.Labels' | \ json2ts -n DockerLabels -o labels.ts --readonly

Tips πŸ’‘

  • Check version: json2ts --version
  • View help: json2ts --help

Programmatic API πŸ“š

Installation

npm install @junaidatari/json2ts # NPM pnpm install @junaidatari/json2ts # PNPM yarn add @junaidatari/json2ts # Yarn

Usage πŸš€

import { JsonToTsConverter, JsonToFlattenedTsConverter, } from '@junaidatari/json2ts'; // Sample JSON object const json = { user: { name: 'John', age: 30, address: { street: '123 Main St', city: 'New York' } } }; // Sample JSON string const jsonText = `{  "_id": "691da8feb00505c1c11b08b9",  "index": 0,  "guid": "9150daa4-b7c4-4230-a3b8-ddd2eb05731f",  "isActive": true,  "balance": "$3,816.81",  "picture": "http://placehold.it/32x32",  "age": 39,  "eyeColor": "blue",  "name": "Vickie Snow",  "gender": "female",  "company": "DATACATOR",  "email": "vickiesnow@datacator.com",  "phone": "+1 (925) 537-2747",  "address": "843 Interborough Parkway, Floris, Washington, 5608",  "registered": "2018-11-01T06:02:48 -05:00",  "latitude": -42.568798,  "longitude": -77.971543,  "tags": [  "fugiat",  "reprehenderit",  "culpa",  "veniam",  "enim",  "occaecat",  "et"  ],  "friends": [  {  "id": 0,  "name": "Silvia Ferrell"  },  {  "id": 1,  "name": "Kirkland Benson"  },  {  "id": 2,  "name": "Howe Hester"  }  ],  "greeting": "Hello, Vickie Snow! You have 10 unread messages.",  "favoriteFruit": "strawberry" } `; // Convert to multiple interfaces with all exports const interfaces = JsonToTsConverter.convert(json, 'Person', 'all'); console.log('Generated interfaces:'); console.log(interfaces); /* Output: export interface Person {  user: User; }  export interface User {  name: string;  age: number;  address: Address; }  export interface Address {  street: string;  city: string; } */ // Convert to flattened interface const interfaceFlat = JsonToFlattenedTsConverter.convert(jsonText, 'PersonFlat', 'all'); console.log('\nGenerated flattened interface:'); console.log(interfaceFlat); /* Output: export interface PersonFlat {  _id: string;  index: number;  guid: string;  isActive: boolean;  balance: string;  picture: string;  age: number;  eyeColor: string;  name: string;  gender: string;  company: string;  email: string;  phone: string;  address: string;  registered: string;  latitude: number;  longitude: number;  tags: string[];  friends: {  id: number;  name: string;  }[];  greeting: string;  favoriteFruit: string; } */ // Example with complex nested structure const complexJson = { data: { users: [ { id: 1, profile: { name: 'Alice', preferences: { theme: 'dark', notifications: { email: true, push: false } } } } ], metadata: { total: 1, page: 1 } } }; const complexTypes = JsonToTsConverter.convert(complexJson, 'ApiResponse', 'root'); console.log(complexTypes); /* Output: export interface ApiResponse {  data: Data; }  interface Data {  users: User[];  metadata: Metadata; }  interface User {  id: number;  profile: Profile; }  interface Profile {  name: string;  preferences: Preferences; }  interface Preferences {  theme: string;  notifications: Notifications; }  interface Notifications {  email: boolean;  push: boolean; }  interface Metadata {  total: number;  page: number; } */ // Real-world example: API response handler async function handleApiResponse() { // Simulate API response const apiResponse = await fetch('https://jsonplaceholder.typicode.com/posts/1'); const data = await apiResponse.json(); // Generate types dynamically const types = JsonToTsConverter.convert(data, 'PostResponse', 'root'); console.log(types); /*  export interface PostResponse {  userId: number;  id: number;  title: string;  body: string;  }  */ }

API Reference πŸ“–

Methods

JsonToTsConverter.convert(json, name?, export?, options?)

JsonToFlattenedTsConverter.convert(json, name?, export?, options?)

Converts JSON to TypeScript interfaces.

Parameters:

  • json: JSON object or string to convert
  • name: Root interface name (default: 'RootObject')
  • export: Export mode ('all', 'root', 'none') (default: 'root')
  • options: Configuration options for conversion (optional)
    • arrayMaxTupleSize: Maximum number of items to convert to tuple type (default: 10)
    • arrayMinTupleSize: Minimum number of items required to create a tuple type (default: 2)
    • strict: Enable strict type checking for better type inference (default: false)
    • typeMap: Custom type mapping for specific JSON structures (default: {})
    • propertyCase: Naming convention for generated property names (default: 'original')
    • readonlyProperties: Make all generated properties readonly (default: false)
    • optionalProperties: Make all generated properties optional (default: false)

Returns: Generated TypeScript interfaces string

Contributing 🀝

We welcome contributions! Please follow these steps:

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup πŸ”§

git clone https://github.com/blacksmoke26/json2ts.git cd json2ts npm install npm run dev npm run dev:flat

Testing CLI with /samples/*.json JSON files

npm run build node .\bin\json2ts -f .\samples\jsons\sample.json -n Sample1 node .\bin\json2ts -f .\samples\jsons\sample2.json -n Sample2 -o sample2.ts --flat

Running test cases

npm run test

License πŸ“„

This project is licensed under the ISC License.

Support πŸ’¬

If you encounter issues or have questions:

Acknowledgments πŸ™

  • Originally developed for Posquelize
  • Thanks to all contributors
  • Inspired by the need for type safety in JSON-heavy applications

Copyright ©️

Developed with ❀️ by Junaid Atari