Generate TypeScript JSON schema files (.ts
modules with as const
assertions) from OpenAPI definitions.
TypeScript JSON schemas serve various purposes, including:
- Validate data and infer validated data TS types with the same JSON schema (with any JSON schema validator like Ajv)
- Infer TS type definitions from JSON schemas (with
json-schema-to-ts
) - Fastify integration: infer route handlers input types from their schema (with
@fastify/type-provider-json-schema-to-ts
)
Given an OpenAPI definition file, openapi-ts-json-schema
will:
- Resolve external/remote
$ref
s and dereference them with@apidevtools/json-schema-ref-parser
- Optionally inline, import or retain local
$ref
s - Convert to JSON schema with
@openapi-contrib/openapi-schema-to-json-schema
andopenapi-jsonschema-parameters
- Generate a TypeScript JSON schema file for each definition (
.ts
files withas const
assertion) - Organizing schemas in a folder structure mirroring the original OpenAPI definition layout.
TypeScript JSON schemas are 100% valid JSON schemas.
npm i openapi-ts-json-schema -D
Generate your TypeScript JSON schemas:
import { openapiToTsJsonSchema } from 'openapi-ts-json-schema';
const { outputPath } = await openapiToTsJsonSchema({
openApiSchema: 'path/to/open-api-specs.yaml',
definitionPathsToGenerateFrom: ['paths', 'components.schemas'],
});
...and use them in your TS project:
import Ajv from 'ajv';
import type { FromSchema } from 'json-schema-to-ts';
import mySchema from 'path/to/generated/schemas/MyModel.ts';
const ajv = new Ajv();
// Perform data validation and type inference using the same schema
const validate = ajv.compile<FromSchema<typeof mySchema>>(mySchema);
const data: unknown = {};
if (validate(data)) {
// data gets type inference
console.log(data.foo);
} else {
console.log(validate.errors);
}
Property | Type | Description | Default |
---|---|---|---|
openApiSchema (required) | string |
Path to the OpenApi file (supports yaml and json). | - |
definitionPathsToGenerateFrom (required) | string[] |
OpenApi definition object paths to generate the JSON schemas from. Only matching paths will be generated. Supports dot notation: ["components.schemas"] . |
- |
refHandling | |||
refHandling.strategy | "import" | "inline" | "keep" |
"import" : generate and import $ref schemas."inline" : inline $ref schemas."keep" : keep $ref values. |
"import" |
refHandling.refMapper | (input: {id: string}) => string |
Customize generated $ref values (only keep strategy) |
- |
schemaPatcher | (params: { schema: JSONSchema }) => void |
Dynamically patch generated JSON schemas. The provided function will be invoked against every single JSON schema node. | - |
outputPath | string |
Path where the generated schemas will be saved. Defaults to /schemas-autogenerated in the same directory of openApiSchema . |
- |
plugins | ReturnType<Plugin>[] |
A set of optional plugins to generate extra custom output. See plugins docs. | - |
silent | boolean |
Don't log user messages. | false |
Take a look at the Developer's notes for a few more in-depth explanations.
openapi-ts-json-schema
provides 3 refHandling
strategies for OpenAPI $ref
properties:
refHandling.strategy option |
|
---|---|
inline |
Replaces $ref s with inline copies of the target definition, creating self-contained schemas with potential redundancy |
import |
Replaces $ref s with a local variable pointing to the module of the target $ref definition |
keep |
Retains $ref s values without modification |
Circular $ref
s references are supported, too:
refHandling.strategy option |
|
---|---|
inline |
Nested circular references are replaced with {} |
import |
Completely resolves the JSON schema tree. However, the TypeScript engine will halt type recursion and assign the schema type as any , resulting in error ts(7022) |
keep |
Does not resolve circular references by definition |
For further details, refer to the relevant tests.
Beside generating the expected schema files under outputPath
, openapiToTsJsonSchema
returns the following meta data:
{
// The path where the schemas are generated
outputPath: string;
metaData: {
// Meta data of the generated schemas
schemas: Map<
// Schema internal di. Eg: "/components/schemas/MySchema"
string,
{
id: string;
// JSON schema Compound Schema Document `$id`. Eg: `"/components/schemas/MySchema"`
uniqueName: string;
// Unique JavaScript identifier used as import name. Eg: `"componentsSchemasMySchema"`
originalSchema: JSONSchema | string;
// Original dereferenced JSON schema
isRef: boolean;
// True if schemas is used as a `$ref`
absoluteDirName: string;
// Absolute path pointing to schema folder (posix or win32). Eg: `"Users/username/output/path/components/schemas"`
absolutePath: string;
// Absolute path pointing to schema file (posix or win32). Eg: `"Users/username/output/path/components/schemas/MySchema.ts"`
absoluteImportPath: string;
// Absolute import path (posix or win32, without extension). Eg: `"Users/username/output/path/components/schemas/MySchema"`
}
>;
}
}
Plugins are intended as a way to generate extra artifacts based on the same internal metadata created to generate the JSON schema output.
openapi-ts-json-schema
currently ships with one plugin specifically designed to better integrate with Fastify, but you can write your own!
Read plugins documentation 📖.
- Consider removing required
definitionPathsToGenerateFrom
option in favour of exporting the whole OpenAPI definitions based on the structure defined in specs - Improve external
#ref
s handling (currently being inlined and duplicated) - Find a way to merge multiple different OpenApi definitions consistently
- Consider adding a way to optionally generate
$id
props (this would clash withimport
ref handling) - Consider implementing an option to inline circular $refs with a configurable nesting level