@ricsam/json-schema-to-typescript
v0.1.0
Published
Generate TypeScript types from JSON Schema definitions
Maintainers
Readme
@ricsam/json-schema-to-typescript
Compile JSON Schema to TypeScript typings - optimized for Bun
A lightweight fork of json-schema-to-typescript designed for use with Bun. This package removes $ref resolution and Prettier formatting to provide a simpler, faster compilation pipeline.
Differences from the Original
| Feature | Original | This Fork |
|---------|----------|-----------|
| $ref resolution | Supported | Not supported - schemas must be pre-dereferenced |
| Prettier formatting | Built-in | Removed - output is unformatted |
| CLI | Included | Removed - API only |
| Runtime | Node.js | Bun |
| YAML support | js-yaml | Bun's built-in YAML parser |
Why these changes?
- No
$refresolution: Many build pipelines already dereference schemas before processing. Removing this dependency simplifies the codebase and reduces bundle size. - No formatting: Formatting can be done separately with your preferred tool (Prettier, Biome, etc.) or skipped entirely for better performance.
- Bun-native: Takes advantage of Bun's built-in APIs and faster runtime.
Example
Input:
{
"title": "Example Schema",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
},
"hairColor": {
"enum": ["black", "brown", "blue"],
"type": "string"
}
},
"additionalProperties": false,
"required": ["firstName", "lastName"]
}Output:
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/
export interface ExampleSchema {
firstName: string
lastName: string
/**
* Age in years
*/
age?: number
hairColor?: "black" | "brown" | "blue"
}Installation
bun add @ricsam/json-schema-to-typescriptUsage
import { compile } from '@ricsam/json-schema-to-typescript'
const mySchema = {
title: 'Person',
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'integer' }
},
required: ['name']
}
const typescript = await compile(mySchema, 'Person')
console.log(typescript)Formatting the Output
Since this package doesn't include formatting, you can format the output yourself:
import { compile } from '@ricsam/json-schema-to-typescript'
const typescript = await compile(schema, 'MySchema')
// Format with Prettier (if installed)
import * as prettier from 'prettier'
const formatted = await prettier.format(typescript, { parser: 'typescript' })
// Or with Biome
// bunx @biomejs/biome format --stdin-file-path=output.ts < output.tsHandling $ref References
This package does not resolve $ref references. If your schema contains references, you must dereference it first:
import { compile } from '@ricsam/json-schema-to-typescript'
import $RefParser from '@apidevtools/json-schema-ref-parser'
// Dereference the schema first
const dereferencedSchema = await $RefParser.dereference('./schema.json')
// Then compile
const typescript = await compile(dereferencedSchema, 'MySchema')Options
The compile function accepts options as its third argument (all keys are optional):
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| additionalProperties | boolean | true | Default value for additionalProperties, when it is not explicitly set |
| bannerComment | string | "/* eslint-disable */..." | Disclaimer comment prepended to the top of each generated file |
| customName | (schema, keyName) => string \| undefined | undefined | Custom function to provide a type name for a given schema |
| enableConstEnums | boolean | true | Prepend enums with const? |
| inferStringEnumKeysFromValues | boolean | false | Create enums from JSON enums with eponymous keys |
| ignoreMinAndMaxItems | boolean | false | Ignore maxItems and minItems for array types, preventing tuples being generated |
| maxItems | number | 20 | Maximum number of unioned tuples to emit when representing bounded-size array types, before falling back to emitting unbounded arrays. Set to -1 to ignore maxItems. |
| strictIndexSignatures | boolean | false | Append all index signatures with \| undefined so that they are strictly typed |
| unknownAny | boolean | true | Use unknown instead of any where possible |
| unreachableDefinitions | boolean | false | Generate code for $defs/definitions that aren't referenced by the schema |
Example with Options
import { compile } from '@ricsam/json-schema-to-typescript'
const typescript = await compile(schema, 'MySchema', {
bannerComment: '// Auto-generated - do not edit',
additionalProperties: false,
strictIndexSignatures: true,
unknownAny: true,
})Tests
bun testSupported Features
- [x]
title=>interface - [x] Primitive types:
array,boolean,integer,number,null,object,string - [x] Homogeneous and heterogeneous enums
- [x] Non/extensible interfaces
- [x] Nested properties
- [x] Schema definitions (
$defs,definitions) - [x]
deprecated - [x]
allOf("intersection") - [x]
anyOf("union") - [x]
oneOf(treated likeanyOf) - [x]
maxItems/minItems(tuple generation) - [x]
additionalPropertiesof type - [x]
patternProperties(partial support) - [x]
extends - [x]
requiredproperties - [x] Literal objects in enum
- [x] Custom TypeScript types via
tsType - [x] Custom enum names via
tsEnumNames - [x]
constvalues
Not Supported
- [ ]
$refresolution - schemas must be pre-dereferenced - [ ] External schema references
- [ ] CLI interface
Custom Schema Properties
tsType: Overrides the type that's generated from the schema. Useful for forcing a type toanyor using custom types.tsEnumNames: Overrides the names used for enum elements. Can also be used to create string enums.
{
"properties": {
"date": {
"tsType": "Date"
},
"status": {
"type": "string",
"enum": ["pending", "active", "closed"],
"tsEnumNames": ["Pending", "Active", "Closed"]
}
}
}Credits
This package is a fork of json-schema-to-typescript by Boris Cherny. All credit for the core implementation goes to the original authors and contributors.
License
MIT
