[typescript-angular] Allow generating discriminator based type visitor#9278
[typescript-angular] Allow generating discriminator based type visitor#9278auke- wants to merge 2 commits into
Conversation
When types which extend a common type and are distinguished based on a discriminator are consumed they are often cast to their specific type which results in error prone boilerplate code. By generating a visitor for those kind of types the various subtypes can be consumed in a type safe manner.
TiFu
left a comment
There was a problem hiding this comment.
Thank you for the PR!
Could we potentially add a generated sample for this?
It would be great to at least see whether the TS code compiles as we don't have any explicit tests.
| if (additionalProperties.containsKey(SUBTYPE_VISITOR)) { | ||
| subtypeVisitor = Boolean.parseBoolean(additionalProperties.get(SUBTYPE_VISITOR).toString()); | ||
| } | ||
|
|
There was a problem hiding this comment.
As you commented above, this change is incompatible with taggedUnions - could we add a check for this here, and output an error & terminate if both options are set?
I am unsure how to implement this though - maybe @macjohnny or @wing328 know more and could shed some light on how this is usually done in other generators.
There was a problem hiding this comment.
The current implementation ignores the subtypeVisitor property when taggedUnions is set, it doesn't (or at least shouldn't) generate non-compilable code.
This could of course be changed in order to throw an exception if that is preferred.
There was a problem hiding this comment.
I think an exception or at least a warning would be useful for users
There was a problem hiding this comment.
I have added support for generating a visitor for tagged unions, so there is no need for this warning anymore.
I have implemented a visitor for the Micronaut OpenAPI generator (see https://github.com/kokuwaio/micronaut-openapi-codegen/pull/66/files) and was actually a bit surprised that the default Java generators didn't support this. Since TypeScript doesn't allow default or overlay methods on interfaces a function is generated to mimic the visitor pattern, next to the visitor interface.
I picked a random example with a discriminator from the current tests, allOf_composition_discriminator: An implementation of the visitor could look like this: Which can be used using the visit function: |
|
@auke- Thanks for PR! |
|
I must say I'm pretty new to TypeScript and just applying the design patterns used in the Java world. It looks like discriminated unions could be used, but when the discriminator is just a string (like in the example) it won't help since the TypeScript compiler doesn't know the possible values. |
|
@auke- I think TS compiler is very powerful so it knows possible values. |
But in the given example it doesn't since the information isn't in the generated typescript files, the |
|
Maybe you are right but instead of string it should be union type for example |
|
The thing is that we have to work with 3rd party OpenAPI specs which we can't change. It would be nice if the OpenAPI generator can handle all kinds of use cases. |
|
Instead of generating we should be generating Otherwise Typescript wouldn't know how to distinguish concrete pet subtypes based on the discriminator. Alternatively - if we're not able to produce correct types - codegen can generate type guards. Visitor pattern looks very alien to this use case in Typescript. Java is different - afaik it doesn't have built-in ways to narrow types down. |
|
From my perspective this would be a nice addition which reduces a lot of error prone boilerplate. The visitor pattern is not only useful for casting types, but provides the means to navigate complex data structures without the loss of type safety and accidentally omitting types. With this change users can opt-in for this behavior and even mix it with other patterns like the ones you suggested. |
When types which extend a common type and are distinguished based on a
discriminator are consumed they are often cast to their specific type
which results in error prone boilerplate code.
By generating a visitor for those kind of types the various subtypes can
be consumed in a type safe manner.
PR checklist
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.For Windows users, please run the script in Git BASH.
master,5.1.x,6.0.x@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)