Skip to content

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

Open

Description

@thirteenthstep

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

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

Extra

Activity

  1. added
    bugSomething isn't working
    openapi-tsRelevant to the openapi-typescript library
    on Feb 11, 2025
  2. fluctus commented on Feb 12, 2025

    @fluctus

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

  3. openint-bot commented on Feb 13, 2025

    @openint-bot

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

  4. fluctus commented on Feb 13, 2025

    @fluctus

    @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/

  5. fluctus commented on Feb 13, 2025

    @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

  6. alex-eri commented on Apr 16, 2026

    @alex-eri

    Same issue

    Generated type is never

            ConfirmationDataExternal: Omit<components["schemas"]["ConfirmationData"], "type"> & Record<string, never> & {
                /**
                 * @description discriminator enum property added by openapi-typescript
                 * @enum {string}
                 */
                type: "ConfirmationDataExternal";
            } & {
                /**
                 * @description discriminator enum property added by openapi-typescript
                 * @enum {string}
                 */
                type: "external";
            };

    expected

            ConfirmationDataExternal: Omit<components["schemas"]["ConfirmationData"], "type"> & Record<string, never> & {
                /**
                 * @description discriminator enum property added by openapi-typescript
                 * @enum {string}
                 */
                type: "external";
            };

    schema

        ConfirmationData:
          description: "Information required to initiate the selected payment confirmation scenario by the user. More about confirmation scenarios: https://yookassa.ru/developers/payment-acceptance/getting-started/payment-process#user-confirmation"
          type: "object"
          properties:
            type:
              $ref: "#/components/schemas/ConfirmationDataType"
            locale:
              $ref: "#/components/schemas/Locale"
          discriminator:
            propertyName: "type"
            mapping:
              redirect: "#/components/schemas/ConfirmationDataRedirect"
              external: "#/components/schemas/ConfirmationDataExternal"
              qr: "#/components/schemas/ConfirmationDataQr"
              embedded: "#/components/schemas/ConfirmationDataEmbedded"
              mobile_application: "#/components/schemas/ConfirmationDataMobileApplication"
          required:
          - "type"
    
    ....
    
        ConfirmationDataType:
          description: "Type of payment confirmation scenario by the user. Possible values: redirect - redirecting the user to a ready-made YooMoney page or a partner's page; external - waiting for the user to confirm the payment independently; qr - generating a QR and displaying it on the payment page so that the user can confirm the payment; embedded - displaying the YooMoney payment widget; mobile_application - redirecting the user to the partner's payment app."
          type: "string"
          enum:
          - "redirect"
          - "external"
          - "qr"
          - "embedded"
          - "mobile_application"
    
    ....
    
        ConfirmationDataExternal:
          type: "object"
          allOf:
          - $ref: "#/components/schemas/ConfirmationData"
          - type: "object"
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingopenapi-tsRelevant to the openapi-typescript library

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions