OpenApi generator does not generate valid code for unions discriminated by property name. Unions (oneOf) work correctly when discriminated by a property value, however the generated code seems to try and combine the property lists from all members of the union. If each member of the union have disjoint sets of required properties, then the union is discriminated, and should be generated as such.
openapi-generator 4.3.1
{
"openapi": "3.0",
"info": {
"title": "Test",
"version": "0.1"
},
"servers": [{
"url": "https://localhost"
}],
"paths": {
"/": {
"get": {
"operationId": "dummyOperation",
"responses": {
"200": {
"description": "Successful operaion",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/aOrB"}
}
}
}
}
}
}
},
"components": {
"schemas": {
"a": {
"type": "object",
"required": ["a", "b"],
"properties": {
"a": {
"type": "string"
},
"b": {
"type": "string"
}
}
},
"b": {
"type": "object",
"required": ["b", "c"],
"properties": {
"b": {
"type": "string"
},
"c": {
"type": "string"
}
}
},
"aOrB": {
"oneOf": [
{"$ref": "#/components/schemas/a"},
{"$ref": "#/components/schemas/b"}
]
}
}
}
}
openapi-generator generate -i test.json -g typescript-fetch --additional-properties=typescriptThreePlus --generate-alias-as-model -o test
After generation, the model file for aOrB is:
export function AOrBFromJSONTyped(json: any, ignoreDiscriminator: boolean): AOrB {
if ((json === undefined) || (json === null)) {
return json;
}
return { ...AFromJSONTyped(json, true), ...BFromJSONTyped(json, true) };
}
export function AOrBToJSON(value?: AOrB | null): any {
if (value === undefined) {
return undefined;
}
if (value === null) {
return null;
}
return { ...AToJSON(value), ...BToJSON(value) };
}
This fails because A and B both contain 'required' parameters, so they cannot be combined by spreading as above.
There are similar PR, but they don't seem to address exactly the same issue:
The generated functions need to discriminate on properties as well as values, something like:
export function AOrBFromJSONTyped(json: any, ignoreDiscriminator: boolean): AOrB {
if ((json === undefined) || (json === null)) {
return json;
}
if (json['a'] != undefined && json['b'] != undefined) {
return AFromJSONTyped(json, true);
} else if (json['b'] != undefined && json['c'] != undefined) {
return BFromJSONTyped(json, true);
}
}
export function AOrBToJSON(value?: AOrB | null): any {
if (value === undefined) {
return undefined;
}
if (value === null) {
return null;
}
if (value.a != undefined && value.b != undefined) {
return AToJSON(value);
} else if (value.b != undefined && value.c != undefined) {
return BToJSON(value);
}
}
In the 'if' statements it would test _all_ the required parameters for that member object in the union.
馃憤 Thanks for opening this issue!
馃彿 I have applied any labels matching special text in your issue.
The team will review the labels and make any necessary changes.
Is this issue going to be addressed or is it a won't fix? I have to decide whether to push an API compatibility breaking change for my application, or if I should wait for openapi-generator to fix this before using the generator.
@keean would you like to implement a fix?
moreover, you could try the newly refactored https://openapi-generator.tech/docs/generators/typescript
Most helpful comment
Is this issue going to be addressed or is it a won't fix? I have to decide whether to push an API compatibility breaking change for my application, or if I should wait for openapi-generator to fix this before using the generator.