JSON Schema to TypeScript
json-schema-to-typescript is a utility that compiles JSON Schemas into TypeScript type declarations, enabling strong typing for data structures defined in JSON. Currently at version 15.0.4, it offers both a command-line interface (CLI) for file-based conversions and a programmatic API for integrating into build processes or applications. It is actively maintained with regular updates. Key differentiators include its robust handling of various JSON Schema features like `allOf`, `anyOf`, `oneOf`, `definitions`, and `$ref` for both local and external references. It aims to provide a reliable way to keep TypeScript types synchronized with JSON Schema definitions, reducing manual type creation and potential discrepancies between data contracts and application code. The library supports customizable options for output formatting, banner comments, and how `additionalProperties` are handled, which is crucial for controlling the strictness of generated types. It's particularly useful for projects consuming APIs or data where JSON Schema is the source of truth, facilitating a 'schema-first' development approach.
Common errors
-
Error: ENOENT: no such file or directory, open 'your-schema.json'
cause The `compileFromFile` function was called with a file path that does not exist or is inaccessible.fixVerify that the path to your JSON Schema file is correct and that the file has appropriate read permissions. Ensure relative paths are resolved correctly, e.g., using `path.join(__dirname, 'your-schema.json')`. -
TypeError: (0, json_schema_to_typescript_1.compile) is not a function
cause This error often indicates a CommonJS module trying to import an ESM-only package, or a bundling/transpilation issue where ES module exports are not correctly resolved.fixEnsure your project is configured for ES modules (e.g., `"type": "module"` in `package.json`) and that you are using `import { compile } from 'json-schema-to-typescript'` syntax. If running directly in Node.js, confirm your file uses `.mjs` extension or `type: module`. -
ReferenceError: require is not defined in ES module scope
cause You are attempting to use `require()` in an ES module (`.mjs` file or `"type": "module"` project) where CommonJS `require` is not available.fixRefactor your imports to use ES module `import` syntax: `import { compile, compileFromFile } from 'json-schema-to-typescript'`. If you need conditional imports, consider dynamic `import()`. -
TS2411: Property 'x' of type 'string | undefined' is not assignable to string index type 'string'.
cause This TypeScript error can occur when `additionalProperties` is implicitly or explicitly `true` in your schema, leading to `[k: string]: any` (or similar) but a property within `properties` is `undefined` due to `strictNullChecks`.fixSet `"additionalProperties": false` in your JSON Schema to disallow undeclared properties, or pass `{ additionalProperties: false }` to the `compile` options. Alternatively, if `additionalProperties` is desired, ensure all explicitly defined properties are not `undefined` or handle them appropriately.
Warnings
- breaking The default behavior for `additionalProperties` was changed in some versions, or its interpretation became stricter. Prior versions might have implicitly allowed additional properties, leading to `[k: string]: any` in generated types. Explicitly setting `additionalProperties` in your schema or via the library's options is highly recommended.
- breaking Handling of `oneOf`, `anyOf`, and `allOf` keywords can sometimes lead to `unknown` types or unexpected union types if the schema is ambiguous or complex. This has seen refinements across major versions to improve type precision, but might alter generated types for certain complex schemas.
- gotcha Performance issues can occur when processing very large or deeply nested JSON Schemas, especially with the default code formatting enabled (which uses Prettier internally).
- deprecated Older versions of the library or specific forks might have different default behaviors or removed features, such as `json-schema-to-typescript-lite` removing CLI support and Prettier integration for a lighter footprint.
- gotcha The library relies on `fs` for file operations (`compileFromFile`), which is a Node.js-specific module. Direct use of `compileFromFile` in a browser environment will fail.
Install
-
npm install json-schema-to-typescript -
yarn add json-schema-to-typescript -
pnpm add json-schema-to-typescript
Imports
- compile
const { compile } = require('json-schema-to-typescript')import { compile } from 'json-schema-to-typescript' - compileFromFile
const { compileFromFile } = require('json-schema-to-typescript')import { compileFromFile } from 'json-schema-to-typescript' - JSONSchema
import type { JSONSchema } from 'json-schema-to-typescript'
Quickstart
import { compile, Options } from 'json-schema-to-typescript';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
async function generateTypes() {
const schemaPath = path.join(process.cwd(), 'schema.json');
const outputPath = path.join(process.cwd(), 'types.d.ts');
const mySchema = {
"title": "UserProfile",
"description": "A schema for user profile data",
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"username": { "type": "string", "minLength": 3, "maxLength": 20 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 120 },
"isActive": { "type": "boolean", "default": true }
},
"required": ["id", "username", "email"]
};
// Save schema to a file for compileFromFile example (optional, but good for demo)
await fs.writeFile(schemaPath, JSON.stringify(mySchema, null, 2));
const options: Partial<Options> = {
bannerComment: "/* eslint-disable */\n/** Automatically generated from JSON Schema */",
additionalProperties: false,
unreachableDefinitions: true
};
try {
// Example 1: Compile from an in-memory JS object
const tsFromObject = await compile(mySchema, 'UserProfile', options);
console.log('Generated from object:\n', tsFromObject);
// Example 2: Compile from a file
const tsFromFile = await compileFromFile(schemaPath, options);
await fs.writeFile(outputPath, tsFromFile);
console.log(`Types generated to ${outputPath}`);
} catch (error) {
console.error('Error generating types:', error);
}
}
generateTypes();