How to generate basic TypeScript interfaces from Swagger schema?
Asked Answered
S

9

67

I'm looking for a way to generate simplistic TypeScript interfaces from a Swagger schema. Most solutions I find are needlessly complicated.

I would like to generate interfaces like this:

export interface IBar {
    a?: string;
    b: number;
    c: Date;
    baz?: IBaz;
}

export interface IBaz {
    d: number;
    color: Color;
}

export enum Color {
    RED = 0,
    GREEN = 1,
    BLUE = 2,
}

From a schema like this:

    {
  "x-generator": "NSwag v11.14.0.0 (NJsonSchema v9.10.24.0 (Newtonsoft.Json v9.0.0.0))",
  "swagger": "2.0",
  "info": {
    "title": "",
    "version": ""
  },
  "schemes": [],
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/api/Foo/GetBarDescriptions": {
      "get": {
        "tags": [
          "Foo"
        ],
        "operationId": "Foo_GetBarDescriptions",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "x-nullable": true
          }
        }
      }
    },
    "/api/Foo/GetBar": {
      "get": {
        "tags": [
          "Foo"
        ],
        "operationId": "Foo_GetBar",
        "parameters": [
          {
            "type": "integer",
            "name": "id",
            "in": "query",
            "required": true,
            "x-nullable": false,
            "format": "int32"
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "schema": {
              "$ref": "#/definitions/Bar"
            },
            "x-nullable": true
          }
        }
      }
    },
    "/api/Foo/SetBar": {
      "post": {
        "tags": [
          "Foo"
        ],
        "operationId": "Foo_SetBar",
        "parameters": [
          {
            "name": "value",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/Bar"
            },
            "x-nullable": true
          }
        ],
        "responses": {
          "204": {
            "description": ""
          }
        }
      }
    }
  },
  "definitions": {
    "Bar": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "B",
        "C"
      ],
      "properties": {
        "A": {
          "type": "string"
        },
        "B": {
          "type": "integer",
          "format": "int32"
        },
        "C": {
          "type": "string",
          "format": "date-time"
        },
        "Baz": {
          "$ref": "#/definitions/Baz"
        }
      }
    },
    "Baz": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "D",
        "Color"
      ],
      "properties": {
        "D": {
          "type": "number",
          "format": "decimal"
        },
        "Color": {
          "$ref": "#/definitions/Color"
        }
      }
    },
    "Color": {
      "type": "integer",
      "description": "",
      "x-enumNames": [
        "RED",
        "GREEN",
        "BLUE"
      ],
      "enum": [
        0,
        1,
        2
      ]
    }
  },
  "parameters": {},
  "responses": {},
  "securityDefinitions": {}
}
Sparkman answered 8/2, 2018 at 19:28 Comment(2)
I might be misunderstanding you or this link, but your generated schema above references NSwag. Its documentation claims to integrate AutoRest (which is listed as one of the solutions listed below). Maybe it's new, but it says The project combines the functionality of Swashbuckle (OpenAPI/Swagger generation) and AutoRest (client generation) in one toolchain. from: github.com/RicoSuter/NSwag . I'm just investigating this myself, will try to comment again when done.Willhite
Yeah, it was pretty painless. The harder part was setting up the project for schema generation, because annotations and other factors have to meet Swagger / NSwag expectations. Since that is already done in the example above, NSwagStudio generated TypeScript with one click, and can save the config for automated toolchain use. My only gripe is that the provided templates are pretty nasty... over 90% of the default generated proxy/client code contains duplication that should be a once-stated separated concern, and the default DTO templates contain unexpected type unions I can't eliminate.Willhite
P
26

I'm using swagger-typescript-api to generate interfaces from swagger schema

npx swagger-typescript-api -p PATH_TO_YOUR_SCHEMA -o ./
Phonograph answered 19/2, 2020 at 2:47 Comment(5)
-o ./ means output directory to be ./ and it is the default value, so it's not necessary to list it explicitly. In addition, maybe parameter -n could be mentioned, which means name of the generated file, by default this is Api.ts. I'm using -n apiObjects.tsTalos
Is there any possibility to put each definition into extra file?Talos
@Talos you can use modular option + NodeJS API + single-http-client options to generate extra filesPhonograph
This was easy to run, but the generated file isn't usable because it has a mysterious generic type parameter.Granulite
@SergeyVolkov do you perhaps have an example of how to do this? I have all the relevant interfaces in my data-contracts.ts, but unfortunately no matter the CLI options I cannot extract them into individual files. What would I need to do to accomplish that?Colwell
A
25

Not sure if that's a sane way to do this, it's the first time I'm playing around with Swagger.

I bumped into the following link and pasted the schema from the project I integrate with. From the top 'Generate Client' menu I chose one of the TypeScript presets and it generated a minimal project where I could extract the bits I needed, interface and classes, etc.

http://editor.swagger.io/#/

I tried running your schema. Here's a small excerpt of the generated code:

export interface Bar {
    "a"?: string;
    "b": number;
    "c": Date;
    "baz"?: Baz;
}

export interface Baz {
    "d": number;
    "color": Color;
}

/**
 * 
 */
export type Color = "0" | "1" | "2";

Maybe with a bit more tweaking it can make exactly what you're looking for.

Further reading may be about tools like https://github.com/swagger-api/swagger-codegen but the online web editor is a quick and dirty way to do this.

Automata answered 20/2, 2018 at 17:16 Comment(1)
For current case I've decided to go with json-schema.org over swagger and use github.com/RSuter/NJsonSchema for generation. I'm still looking for a sweet-spot generator for future cases (for NodeJS of course), preferably one that uses JS interpolated strings over third-party template engines.Sparkman
D
13

I use dtsgen and it works well in my case.

yarn dtsgen --out ./path/to/generated-types.d.ts ./path/to/input/swagger.json.or.yml
Diep answered 8/4, 2019 at 6:38 Comment(0)
A
6

You can also take a look at autorest.typescript client code generator. It provides good interfaces for all the model definitions, accurately defines readonly properties and enums. It supports a bunch of custom extensions that can be useful to improve the user experience of the generated client. You can take a look at some generated sample clients.

Bonus: The generated typescript client works in node.js and also in the browser with the help of webpack.

Angara answered 7/3, 2018 at 6:20 Comment(0)
D
6

You can try this tool sw2dts, which generated code like below:

export interface Bar {
    A?: string;
    B: number; // int32
    C: string; // date-time
    Baz?: Baz;
}
export interface Baz {
    D: number; // decimal
    Color: Color;
}
/**
 * 
 */
export type Color = 0 | 1 | 2;

The Color enum seems to need a little tweak, that should contain the names of properties to iterate over, instead of the real number.

Drench answered 3/12, 2018 at 8:59 Comment(0)
F
5

I was looking for a package that will generate just types, not any runnable code. I think this is the same requirement as in the question. The closest I have found that generates just types is this package:

https://www.npmjs.com/package/@manifoldco/swagger-to-ts

Using 2.0.0 of @manifoldco/swagger-to-ts will generate this for the schema in the question:

/**
 * This file was auto-generated by swagger-to-ts.
 * Do not make direct changes to the file.
 */

export interface definitions {
  Bar: { A?: string; B: number; C: string; Baz?: definitions["Baz"] };
  Baz: { D: number; Color: definitions["Color"] };
  Color: "0" | "1" | "2";
}

NOTE: There is a package named like this one without any organizational prefix. Make sure you try the one with the @manifoldco prefix. At first I missed this detail and was very confused :-).

Fireplug answered 27/6, 2020 at 12:26 Comment(1)
This package is deprecated. It's replaced by: npmjs.com/package/openapi-typescriptStedt
G
4
  1. Fisrt download schema.json file from swagar
  2. install openapi(it is available for javascript and typescript as well)
  3. Run
npx openapi-typescript https://example.com/swagger/v1/swagger.json --output generated-type.ts

Now you can see in you project folder a .ts file created. (I put the exmaple for .ts file whoever is using .js the put .js instead of .ts)

Grotius answered 2/6, 2022 at 7:46 Comment(1)
Doesn't work. Complains about invalid JSON -- in the same file that other generators can use.Granulite
G
2

Inspired by https://mcmap.net/q/297166/-generate-nodejs-from-swagger-spec:

Swagger Codegen generates server stubs and client SDKs for a variety of languages and frameworks, including Node.js.

To generate a Node.js server stub, run codegen with the -l nodejs-server argument.

example (Mac):

swagger-codegen generate -l typescript-angular -i swagger.yaml -o ~/Downloads/ts-test
Gussiegussman answered 6/6, 2019 at 19:1 Comment(0)
C
1

You can also just generate each interface from each schema with a simple json to typescript converter http://json2ts.com/. It's not fully automated but better than nothing... and simple.

Clinkscales answered 20/9, 2018 at 15:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.