# Generating JSON Schema From Typescript Types

> Use the ts-json-schema-generator package to generate a valid JSON schema from your TypeScript types.

- Canonical: https://dennisokeeffe.com/blog/2021-12-09-generating-json-schema-from-typescript-types
- Published: 2021-12-09
- Updated: 2021-12-09
- Tags: typescript, json

This post will outline how you can use the [**ts-json-schema-generator**](https://github.com/vega/ts-json-schema-generator) package to generate a JSON schema from your TypeScript types.

## Prerequisites

1. A working repository with a TypeScript project.

## Our code to generate the types

The script itself is written with JavaScript with the following code:

```js
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:

1. Generates a schema using the configuration in `config`.
2. 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:

```ts
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`:

```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](https://github.com/vega/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

1. [ts-json-schema-generator](https://github.com/vega/ts-json-schema-generator).

_Photo credit: [`impatrickt`](https://unsplash.com/@impatrickt)_
