-
-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
First off - there are many issues dancing around this issue (I've spent half a day trying to identify the rhyme/reason for the current behavior). None, however, specifically target the typescript-node
generator. The typescript-*
generators share no templates, though it appears the new typescript
generator has some copypasta from typescript-node
.
There are two issues I'm addressing here:
- Models specified using
oneOf
are not generated properly ObjectSerializer
does not properly handlediscriminator
Point 2 is fairly self-explanatory, but I'll elaborate: the discriminator
property allows for a mapping
object. The current implementation assumes the discriminator
property is the name of a class:
var discriminatorType = data[discriminatorProperty];
if(typeMap[discriminatorType]){
return discriminatorType; // use the type given in the discriminator
} else {
return expectedType; // discriminator did not map to a type
}
Point 1 is a bit gnarlier. In the attached example, the class Message
is generated as a superset of ALL subclass properties. This makes it a big damn mess and could lead to unexpected results in the event that subclasses define properties using the same names. If you attempt to call ObjectSerializer.deserialize(data, 'Message')
, it deserializes what should be a FooMessage
as a Message
. If you don't care about the typing, however, the properties are all there, at least.
openapi-generator version
5.1.1
, main
(5.2.1-SNAPSHOT
as of this writing)
OpenAPI declaration file content or url
openapi: 3.0.3
info:
description: Example
version: '1.2.3'
title: 'example'
paths:
/foo:
get:
tags:
- foo
operationId: getFoo
responses:
'204':
description: Foo
components:
schemas:
MessageOperation:
description: Message operation
type: string
enum:
- foo_op
- bar_op
Message:
type: object
description: Any message
oneOf:
- $ref: '#/components/schemas/FooMessage'
- $ref: '#/components/schemas/BarMessage'
discriminator:
propertyName: operation
mapping:
foo_op: '#/components/schemas/FooMessage'
bar_op: '#/components/schemas/BarMessage'
MessageBase:
type: object
description: Base class for a message
required:
- id
- operation
- error
- timestamp
properties:
id:
type: string
format: uuid
description: A unique ID for this message
operation:
description: The operation to be performed
$ref: '#/components/schemas/MessageOperation'
error:
type: boolean
default: false
description: Indicates whether or not this is an error message
timestamp:
type: string
format: date-time
description: The time when this message was sent
FooMessage:
description: A Foo message
type: object
allOf:
- $ref: '#/components/schemas/MessageBase'
- type: object
required:
- foo
properties:
foo:
type: string
BarMessage:
description: A Bar message
type: object
allOf:
- $ref: '#/components/schemas/MessageBase'
- type: object
required:
- bar
properties:
bar:
type: string
Generation Details
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g typescript-node -i ./poly.yaml -o tmp/
Steps to reproduce
Generate code
Related issues/PRs
#6376 #9305 #4374 #15 #10017 #6513
Suggest a fix
My proposed solution here is two-fold:
- Generate a
typedef
for so-called tagged union types. Thetypescript-axios
generator does this currently, and I believe it results in much cleaner generated code. Depending on how people use the generated code, this will be a breaking change (if anyone is using the base class). - Encapsulate the contents of the
discriminator.mapping
intoObjectSerializer
to allow deserializing an e.g.Message
intoFooMessage
orBarMessage
, as determined by the value ofdiscriminator
. The current behavior can be kept as a fallback.
I'm currently working on a PR for these but would like some feedback from the TS team. :)
CC @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @topce (2018/10) @akehir (2019/07) @petejohansonxo (2019/11) @amakhrov (2020/02)