openapi-typescript-codegen
openapi-typescript-codegen copied to clipboard
Discriminators not working for oneOf when the members are allOf schemas
Great tool! Thanks for all the effort.
While generating an API I found out discriminators aren't working for oneOf schemas that consist of a list of schemas that themselves are composed with allOf.
It's not easy to explain with a few words. I create a repository that reproduces the issue and explained in more detail in the readme there, comparing a working example and the case that fails.
https://github.com/gillchristian/openapi-typescript-codegen-discriminator-report
@gillchristian I'm currently stuck with the same issue. Have you found a workaround for making this work in the meantime?
That's a good solution!
I've come up with another one that could be helpful for some. By removing the DiscriminatorType and using enums with just one entry for the discriminated type, you can get the codegen to generate valid code.
An example, based on your example code:
components:
schemas:
Base:
type: object
required:
- id
properties:
id:
type: string
One:
allOf:
- '$ref': '#/components/schemas/Base'
- type: object
required:
- tag
- one
properties:
tag:
type: string
enum: [one]
one:
type: string
Two:
allOf:
- '$ref': '#/components/schemas/Base'
- type: object
required:
- tag
- two
properties:
tag:
type: string
enum: [two]
two:
type: string
DiscriminatorComplex:
discriminator:
propertyName: tag
mapping:
one: '#/components/schemas/One'
two: '#/components/schemas/Two'
oneOf:
- '$ref': '#/components/schemas/One'
- '$ref': '#/components/schemas/Two'
If you want the DiscriminatorType as a type in TS, you can export it with:
export type DiscriminatorType = DiscriminatorComplex["tag"];
We also encountered this issue. The workarounds don't scale that well. You need a lot of extra code that can also introduce errors. It would be really nice if the generation would respect the discriminators.
any progress on this?
If this is implemented, it will be the only typescript client generator that works for my use case.
In the meantime, I've coped with the limitation by writing a transformation that inlines the allOf. The result is structurally equivalent in terms of the resulting types.
It seems this would be expressible via an intersection & on the base type with an Omit on the discriminator field to prevent widening it back to string.