A powerful tool that automatically generates TypeScript interfaces from JSON objects, making type-safe development easier and more efficient.
- π§ 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
--flatflag - βοΈ 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
--strictflag - π Read-only Properties: Generate immutable interfaces with
readonlymodifier - β 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
- Primitive arrays (e.g.,
- πΊοΈ 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"toUserIDtype - Configure via
typeMapoption in API or CLI
The package includes a command-line interface (CLI) for quick conversions without writing code.
npm install -g @junaidatari/json2ts # NPM pnpm install -g @junaidatari/json2ts # PNPM yarn global add @junaidatari/json2ts # Yarn| 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.
json2ts -f input.json -o types.ts -n ApiResponse# Linux/Mac json2ts -t '{"user": {"name": "John"}}' -n User # Windows json2ts -t "{\"user\": {\"name\": \"John\"}}" -n User# 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# 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 --optionaljson2ts -f complex.json -o flat-types.ts -n Data --flatjson2ts -f input.json -o types.ts -n Response -e ajson2ts -f input.json -o types.ts -n Response --export n# 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# Generate with strict type checking json2ts -f input.json -o strict-types.ts -n Data --strict# 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# 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 rcurl -s https://jsonplaceholder.typicode.com/posts/1 | \ json2ts -n UserResponse -o user-types.ts# 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# 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# 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.tsecho '{"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# 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"' {} \;for file in data/*.json; do base=$(basename "$file" .json) json2ts -f "$file" -o "types/${base}.ts" -n "${base^}Data" done# 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# 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# 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# 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# 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# 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# 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- Check version:
json2ts --version - View help:
json2ts --help
npm install @junaidatari/json2ts # NPM pnpm install @junaidatari/json2ts # PNPM yarn add @junaidatari/json2ts # Yarnimport { 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; } */ }Converts JSON to TypeScript interfaces.
Parameters:
json: JSON object or string to convertname: 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
We welcome contributions! Please follow these steps:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
git clone https://github.com/blacksmoke26/json2ts.git cd json2ts npm install npm run dev npm run dev:flatnpm 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 --flatnpm run testThis project is licensed under the ISC License.
If you encounter issues or have questions:
- Search existing GitHub Issues
- Create a new issue
- Originally developed for Posquelize
- Thanks to all contributors
- Inspired by the need for type safety in JSON-heavy applications
Developed with β€οΈ by Junaid Atari