openapi-ts icon indicating copy to clipboard operation
openapi-ts copied to clipboard

Enum are not used inside types

Open MeCapron opened this issue 7 months ago • 1 comments

Description

Hello,

when having enum for a specific type it's properly created but never used in the actual type. Is there some limitations or something?

The simple OpenAPI spec given below produce this output :

// This file is auto-generated by @hey-api/openapi-ts

/**
 * pet status in the store
 */
export type Status = 'available' | 'pending' | 'sold';

/**
 * pet status in the store
 */
export const Status = {
    AVAILABLE: 'available',
    PENDING: 'pending',
    SOLD: 'sold'
} as const;

export type Pet = {
    id?: number;
    name: string;
    /**
     * pet status in the store
     */
    status?: 'available' | 'pending' | 'sold';
};

export type Pet2 = Pet;

export type UpdatePetData = {
    /**
     * Update an existent pet in the store
     */
    body: Pet;
    path?: never;
    query?: never;
    url: '/pet';
};

export type UpdatePetResponses = {
    /**
     * Successful operation
     */
    200: Pet;
};

export type UpdatePetResponse = UpdatePetResponses[keyof UpdatePetResponses];

export type ClientOptions = {
    baseUrl: 'https://petstore3.swagger.io/api/v3' | (string & {});
};

I was expecting Pet type to use the actual enum

Reproducible example or configuration

  • Use the given OpenAPI spec
  • Generate types using HeyAPI
  • Open the types.gen.ts and check the output

OpenAPI specification (optional)

{
  "openapi": "3.0.4",
  "info": {
    "title": "Swagger Petstore - OpenAPI 3.0",
    "description": "This is a sample Pet Store Server based on the OpenAPI 3.0 specification.  You can find out more about\nSwagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!\nYou can now help us improve the API whether it's by making changes to the definition itself or to the code.\nThat way, with time, we can improve the API in general, and expose some of the new features in OAS3.\n\nSome useful links:\n- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)\n- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)",
    "termsOfService": "https://swagger.io/terms/",
    "contact": {
      "email": "[email protected]"
    },
    "license": {
      "name": "Apache 2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
    },
    "version": "1.0.12"
  },
  "externalDocs": {
    "description": "Find out more about Swagger",
    "url": "https://swagger.io"
  },
  "servers": [
    {
      "url": "https://petstore3.swagger.io/api/v3"
    }
  ],
  "tags": [
    {
      "name": "pet",
      "description": "Everything about your Pets",
      "externalDocs": {
        "description": "Find out more",
        "url": "https://swagger.io"
      }
    }
  ],
  "paths": {
    "/pet": {
      "put": {
        "tags": [
          "pet"
        ],
        "summary": "Update an existing pet.",
        "description": "Update an existing pet by Id.",
        "operationId": "updatePet",
        "requestBody": {
          "description": "Update an existent pet in the store",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Pet"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Pet": {
        "required": [
          "name",
          "photoUrls"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "example": 10
          },
          "name": {
            "type": "string",
            "example": "doggie"
          },
          "status": {
            "type": "string",
            "description": "pet status in the store",
            "enum": [
              "available",
              "pending",
              "sold"
            ]
          }
        }
      }
    },
    "requestBodies": {
      "Pet": {
        "description": "Pet object that needs to be added to the store",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Pet"
            }
          }
        }
      }
    }
  }
}

System information (optional)

No response

MeCapron avatar Apr 24 '25 13:04 MeCapron

Try adding the following to your openapi-ts.config

{
      enums: 'typescript',
      name: '@hey-api/typescript',
},

https://heyapi.dev/openapi-ts/output/typescript#enums

josh-rymer avatar Jun 16 '25 16:06 josh-rymer

Bumping this. @josh-rymer That will generate the enum types, but the generated enum types are not used inside the defining type.

tervay avatar Jun 16 '25 20:06 tervay

To give some more insights : it doesn't matter for most of the case since TypeScript doesn't really care about the type but instead look at values.

However, it becomes pretty handy when writing custom plugins for HeyAPI that'll actually analyze the type.

As an example, I can tell about NestJS. I wrote a specific plugin so I don't have to rewrite all the types but still can expose them in documentation.

Using the real enum in the field would allow NestJS to actually create a type in the swagger

MeCapron avatar Jun 17 '25 09:06 MeCapron

Hey! In v0.78.0, you can add a transform to make this work

export default {
  input: './spec.json',
  output: './src/client',
  parser: {
    transforms: {
      enums: 'root', // <- make enums reusable
    },
  },
  plugins: [
    {
      enums: 'typescript',
      name: '@hey-api/typescript',
    },
    // other plugins
  ],
};

You can read more about it in the new Parser docs

mrlubos avatar Jul 04 '25 20:07 mrlubos

Hey! In v0.78.0, you can add a transform to make this work

export default { input: './spec.json', output: './src/client', parser: { transforms: { enums: 'root', // <- make enums reusable }, }, plugins: [ { enums: 'typescript', name: '@hey-api/typescript', }, // other plugins ], }; You can read more about it in the new Parser docs

Thanks for the nice work @mrlubos !

MeCapron avatar Jul 05 '25 09:07 MeCapron