loading...
Cover image for Generate TypeScript types from Swagger (OpenAPI 3)

Generate TypeScript types from Swagger (OpenAPI 3)

pavelkeyzik profile image Pavel Keyzik ・2 min read

Hi! I'd like to share some code that helped me a lot to work with an API that had been changed often.

Idea

The idea is to generate TypeScript types from Swagger's definition. I found an awesome npm library called @codegena/oapi3ts-cli. To use this you need to store JSON file with API schema locally.

Let's move to code...

Install dependencies

I used axios to fetch data. You can use anything you want.

npm i -D @codegena/oapi3ts-cli axios

Create folders and files that we need

Now let's create the scripts/ folder in the root of your project and add two files (fetch-schema.js and schema-codegen.js) inside of the created folder. Also, we need to create src/typings/ folder where we're gonna save our types and API schema.

// scripts/schema-codegen.json

const cliLib = require('@codegena/oapi3ts-cli');
const cliApp = new cliLib.CliApplication();

cliApp.cliConfig.typingsDirectory = '';
cliApp.createTypings();
// scripts/fetch-schema.json

const axios = require('axios');
const https = require('https');
const fs = require('fs');
const path = require('path');

const instance = axios.create({
  httpsAgent: new https.Agent({
    rejectUnauthorized: false,
  }),
});


/* The code below will create operation names.
Instead of `/api/User/GetList` you'll get `UserGetList` type
that you can use anywhere */

function addOperationIdsToSchema(schema) {
  const data = schema;

  Object.keys(data.paths).forEach((endpointPath) => {
    const operations = Object.keys(data.paths[endpointPath]);

    operations.forEach((operation) => {
      const oprationName = endpointPath.replace('/api/', '').replace(/\//g, '');
      data.paths[endpointPath][operation].operationId = oprationName;
    });
  });

  return data;
}

instance
  .get('https://YOUR_ENDPOINT_TO_SWAGGER/swagger.json')
  .then((response) => {
    const updatedSchema = addOperationIdsToSchema(response.data);
    fs.writeFileSync(
      path.resolve(__dirname, '../src/typings/api-schema.json'),
      JSON.stringify(updatedSchema, null, 2),
    );

    console.log('==> Schema fetched successfully...');
  })
  .catch(console.error);

Update package.json

And one of the last things you need to do is add to package.json these lines:

{
    ...
    "scripts": {
        ...
        "schema:fetch": "node ./scripts/fetch-schema.js",
        "schema:generate": "node ./scripts/schema-codegen.js --srcPath ./src/typings/api-schema.json --destPath ./src/typings/api --separatedFiles false",
        "schema:codegen": "npm run schema:fetch && npm run schema:generate:api"
    }
}

Now you can generate your API schema with this command:

npm run schema:codegen

This command generated src/typings/api/ folder with TypeScript definitions.

If you got into some problems, please, let me know to be able to update the article for future readers.

Posted on by:

pavelkeyzik profile

Pavel Keyzik

@pavelkeyzik

Front-end developer. Two things that I love most is React and automotive photography.

Discussion

pic
Editor guide