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

Discriminator values are generated using the name of referenced types instead of the actual property value

Open thirteenthstep opened this issue 9 months ago • 4 comments

openapi-typescript version

7.6.1

Node.js version

22.12.0

OS + version

macOs 15.3

Description

If the schema declares a oneOf property with discriminator the generated Types will have their name as discriminator value.

Reproduction

Example Schema:

openapi: 3.0.3

components:
  schemas:
    Post:
      properties:
        comments:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/TextComment'
              - $ref: '#/components/schemas/QuoteComment'
            discriminator:
              propertyName: commentType
    TextComment:
      type: object
      required:
        - commentType
      properties:
        commentType:
          type: string
          enum:
            - text
    QuoteComment:
      type: object
      required:
        - commentType
      properties:
        commentType:
          type: string
          enum:
            - quote

Output:

schemas: {
        Post: {
            comments?: (components["schemas"]["TextComment"] | components["schemas"]["QuoteComment"])[];
        };
        TextComment: {
            /**
             * @description discriminator enum property added by openapi-typescript
             * @enum {string}
             */
            commentType: "TextComment";
        };
        QuoteComment: {
            /**
             * @description discriminator enum property added by openapi-typescript
             * @enum {string}
             */
            commentType: "QuoteComment";
        };

Where actual values of commentType should be text|quote. This issue does not occur if

            discriminator:
              propertyName: commentType

is absent, or if the types are not nested/referenced at all.

Expected result

schemas: {
        Post: {
            comments?: (components["schemas"]["TextComment"] | components["schemas"]["QuoteComment"])[];
        };
        TextComment: {
            /**
             * @description discriminator enum property added by openapi-typescript
             * @enum {string}
             */
            commentType: "text";
        };
        QuoteComment: {
            /**
             * @description discriminator enum property added by openapi-typescript
             * @enum {string}
             */
            commentType: "quote";
        };

Required

  • [x] My OpenAPI schema is valid and passes the Redocly validator (npx @redocly/cli@latest lint)

Extra

thirteenthstep avatar Feb 11 '25 04:02 thirteenthstep

+1 @thirteenthstep It does not happen when using mapping, but discriminator mapping is not supported when validating with ajv.

fluctus avatar Feb 12 '25 17:02 fluctus

just ran into this also @fluctus what do you mean when using mapping? Do you have a workaround?

openint-bot avatar Feb 13 '25 12:02 openint-bot

@thirteenthstep The current implementation seems to match what is written in swagger.io about discriminator without mapping:

In our example, the discriminator points to the objectType property that contains the data type name.

https://swagger.io/docs/specification/v3_0/data-models/inheritance-and-polymorphism/

fluctus avatar Feb 13 '25 17:02 fluctus

@openapi-ts-bot You can define mapping under discriminator, the mapping will be used as the discriminator values in the generated types. Read about in the link in the comment above

fluctus avatar Feb 13 '25 17:02 fluctus