DEV Community

Cover image for Generate TypeScript types from Swagger (OpenAPI 3)
Pavel Keyzik
Pavel Keyzik

Posted on • Edited on • Originally published at pavelkeyzik.com

9 3

Generate TypeScript types from Swagger (OpenAPI 3)

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
Enter fullscreen mode Exit fullscreen mode

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.js

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

cliApp.cliConfig.typingsDirectory = '';
cliApp.createTypings();
Enter fullscreen mode Exit fullscreen mode
// scripts/fetch-schema.js

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);
Enter fullscreen mode Exit fullscreen mode

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"
    }
}
Enter fullscreen mode Exit fullscreen mode

Now you can generate your API schema with this command:

npm run schema:codegen
Enter fullscreen mode Exit fullscreen mode

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.

Neon image

Set up a Neon project in seconds and connect from a Next.js application

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

Top comments (4)

Collapse
 
hilleer profile image
Daniel Hillmann • Edited

this is a bit weird. You explicitly include cli in the name but I only see examples of using it programmatically? Did I misunderstand or overlook something? :-)

Otherwise seem cool.

en.wikipedia.org/wiki/Command-line...

Collapse
 
pavelkeyzik profile image
Pavel Keyzik

I agree that it seems to be weird but I haven't found anything else in docs of that package.

Collapse
 
thomasganter profile image
Thomas Ganter

Nice, and I’ll give it a try, but … you might want to correct the first line of those example files, for they are not json but js …

Collapse
 
pavelkeyzik profile image
Pavel Keyzik

Oh, yeah! I'll fix that. Thank you so much

👋 Kindness is contagious

Dive into this informative piece, backed by our vibrant DEV Community

Whether you’re a novice or a pro, your perspective enriches our collective insight.

A simple “thank you” can lift someone’s spirits—share your gratitude in the comments!

On DEV, the power of shared knowledge paves a smoother path and tightens our community ties. Found value here? A quick thanks to the author makes a big impact.

Okay