Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discriminator not working as expected in TypeScript client #4326

Closed
jabrks opened this issue Mar 12, 2024 · 2 comments
Closed

Discriminator not working as expected in TypeScript client #4326

jabrks opened this issue Mar 12, 2024 · 2 comments
Labels
duplicate This issue or pull request already exists enhancement New feature or request TypeScript Pull requests that update Javascript code

Comments

@jabrks
Copy link

jabrks commented Mar 12, 2024

I'm not sure if this is a bug or limitation of Kiota, or if there is something I have defined incorrectly in my OpenAPI specification, so apologies if this turns out to be the latter.

I have generated a TypeScript client with the following command from the OpenAPI specification included below

kiota generate -l typescript -d openapi.yml -c ApiClient -o ./kiota
openapi: 3.0.1
info:
  title: Survey API
  version: 1.0.0
paths:
  /api/v1/answer:
    post:
      operationId: submitAnswer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmitAnswerRequest'
        required: true
      responses:
        '201':
          content:
            '*/*': {}
          description: Answer a question
components:
  schemas:
    SubmitAnswerRequest:
      type: object
      discriminator:
        mapping:
          TEXT: '#/components/schemas/SubmitTextAnswerRequest'
          BOOLEAN: '#/components/schemas/SubmitBooleanAnswerRequest'
        propertyName: answerType
      oneOf:
        - $ref: '#/components/schemas/SubmitTextAnswerRequest'
        - $ref: '#/components/schemas/SubmitBooleanAnswerRequest'
      properties:
        answerType:
          $ref: '#/components/schemas/AnswerType'
      required:
        - answerType
    SubmitTextAnswerRequest:
      type: object
      allOf:
        - $ref: '#/components/schemas/SubmitAnswerRequest'
        - type: object
          properties:
            answer:
              type: string
      required:
        - answerType
    SubmitBooleanAnswerRequest:
      type: object
      allOf:
        - $ref: '#/components/schemas/SubmitAnswerRequest'
        - type: object
          properties:
            answer:
              type: boolean
      required:
        - answerType
    AnswerType:
      type: string
      enum:
        - TEXT
        - BOOLEAN

The resulting client is not behaving as expected

// ❌ This should result in a type error because answer is not a boolean
client.api.v1.answer.post({ answerType: 'BOOLEAN', answer: 'true' });

// ❌ This should result in a type error because answer is not a string
client.api.v1.answer.post({ answerType: 'TEXT', answer: true });

// ✅ This should not result in a type error because answer is a boolean
client.api.v1.answer.post({ answerType: 'BOOLEAN', answer: true });

// ✅ This should not result in a type error because answer is a string
client.api.v1.answer.post({ answerType: 'TEXT', answer: 'true' });

Instead, all of these calls are deemed valid. I think this is because the code output from Kiota does not include the answerType in the generated SubmitTextAnswerRequest and SubmitBooleanAnswerRequest

export type AnswerType = (typeof AnswerTypeObject)[keyof typeof AnswerTypeObject];

export interface SubmitAnswerRequest extends AdditionalDataHolder, Parsable {
  additionalData?: Record<string, unknown>;
  answerType?: AnswerType;
}

export interface SubmitBooleanAnswerRequest extends Parsable, SubmitAnswerRequest {
  answer?: boolean;
}

export interface SubmitTextAnswerRequest extends Parsable, SubmitAnswerRequest {
  answer?: string;
}

export const AnswerTypeObject = {
  TEXT: "TEXT",
  BOOLEAN: "BOOLEAN",
} as const;

I would expect these types to include answerType to narrow the value to only the relevant answer type, but it's possible that I am simply misunderstanding how Kiota is intended to work in these scenarios.

Any guidance would be appreciated

@baywet
Copy link
Member

baywet commented Mar 19, 2024

Hi @jabrks,
Thanks for using kiota and for reaching out.
TypeScript generation currently does not support composed types (other than inheritance) generation.
#1812

This is one of the last items we have on the roadmap to make the language stable.
I'm going to go ahead and close this issue as duplicated, can you jump onto that issue and provide more details about your expectations? (TypeScript being one of the only languages that support union and intersection types, we could model it either with wrapper types like the other languages, or use native language features)

@baywet baywet closed this as not planned Won't fix, can't repro, duplicate, stale Mar 19, 2024
@github-project-automation github-project-automation bot moved this from Todo to Done in Kiota Mar 19, 2024
@baywet baywet added duplicate This issue or pull request already exists enhancement New feature or request TypeScript Pull requests that update Javascript code labels Mar 19, 2024
@jabrks
Copy link
Author

jabrks commented Mar 19, 2024

Hi @baywet, thanks for getting back to me and sorry for the duplicate! I will add a comment to the issue you've linked with a summary of the expected behaviour as requested

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists enhancement New feature or request TypeScript Pull requests that update Javascript code
Projects
Archived in project
Development

No branches or pull requests

2 participants