Generating JSON Schema From Typescript Types
Use the ts-json-schema-generator package to generate a valid JSON schema from your TypeScript types.
On this page
This post will outline how you can use the ts-json-schema-generator package to generate a JSON schema from your TypeScript types.
Prerequisites
- A working repository with a TypeScript project.
Our code to generate the types
The script itself is written with JavaScript with the following code:
const tsj = require("ts-json-schema-generator");
const path = require("path");
const fs = require("fs");
const config = {
path: path.join(__dirname, "../src/common/types/entities/api.ts"),
tsconfig: path.join(__dirname, "../tsconfig.json"),
type: "*", // Or <type-name> if you want to generate schema for that one type only
};
const schema_path = path.join(__dirname, "../__generated__/schema.json");
function writeSchema(schema) {
const schemaString = JSON.stringify(schema, null, 2);
fs.writeFileSync(schema_path, schemaString);
}
function generateSchema() {
return tsj.createGenerator(config).createSchema(config.type);
}
function main() {
const output = generateSchema();
writeSchema(output);
}
main();
My script was locally kept in the scripts directory, which may help with the relative paths.
It would read a types file from src/common/types/entities/api.ts and the root tsconfig.json file.
The code does the following:
- Generates a schema using the configuration in
config. - Outputs that schema to
__generated__/schema.json.
Note that it expected the __generated__ folder to already exist - you can change the code to do this automatically for you with the fs module if you would like.
In this example, I only wrote up a script in JavaScript (not TypeScript) that you may want to augment with your own code.
The types file
My target file src/common/types/entities/api.ts has the following:
type UserRole = "USER" | "SUPERUSER";
type User = {
id: string;
email: string | null;
name: string | null;
emailVerified: Date | null;
image: string | null;
role: UserRole;
};
type Post = {
id: string;
createdAt: Date;
updatedAt: Date;
title: string;
content: string | null;
published: boolean;
authorId: string;
};
Running the script
If you run the script (in my case using node scripts/generate-schema.js), the following will be output to __generated__/schema.json:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"User": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"email": {
"type": ["string", "null"]
},
"name": {
"type": ["string", "null"],
"x-faker": "name.findName"
},
"emailVerified": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
]
},
"image": {
"type": ["string", "null"]
},
"role": {
"$ref": "#/definitions/UserRole"
}
},
"required": ["id", "email", "name", "emailVerified", "image", "role"],
"additionalProperties": false,
"description": "Model User"
},
"UserRole": {
"type": "string",
"enum": ["USER", "SUPERUSER"],
"description": "Enums"
},
"Post": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time"
},
"title": {
"type": "string"
},
"content": {
"type": ["string", "null"]
},
"published": {
"type": "boolean"
},
"authorId": {
"type": "string"
}
},
"required": [
"id",
"createdAt",
"updatedAt",
"title",
"content",
"published",
"authorId"
],
"additionalProperties": false,
"description": "Model Post"
}
}
}
Summary
Today's post demonstrated how to output a valid JSON schema using the package ts-json-schema-generator.
This can be useful in standardizing the JSON schema for your API based on a particular set of type definitions.
Resources and further reading
Photo credit: impatrickt