Skip to content

Support for sealed classes containing tagged unions #937

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

Closed
wants to merge 2 commits into from

Conversation

Nthalk
Copy link

@Nthalk Nthalk commented Jan 17, 2023

This uses the proposal of FasterXML/jackson-module-kotlin#239 and the general solution of FasterXML/jackson-module-kotlin#240 to import subtypes of a sealed object or interface that are annotated with @JsonTypeName and assignable to the container class or interface to create a much less verbose method of generating tagged unions.

Sealed types are supported in kotlin 1.6+ and Java 17+, however, we don't really need the sealed functionality, as we are an offline, one-shot generator, this may work to generate the correct type mappings, but fail to parse on the runtime object mapper side unless the user is using the supported kotlin and java versions.

This adds the Maven Wrapper (https://maven.apache.org/wrapper/) for developers that may need to deal with multiple versions of maven on their workstations.
This uses the proposal of FasterXML/jackson-module-kotlin#239 and the general solution of FasterXML/jackson-module-kotlin#240 to import subtypes of a sealed object or interface that are annotated with `@JsonTypeName` and assignable to the container class or interface to create a much less verbose method of generating tagged unions.

Sealed types are supported in kotlin 1.6+ and Java 17+, however, we don't really need the sealed functionality, as we are an offline, one-shot generator, this may work to generate the correct type mappings, but fail to parse on the runtime object mapper side unless the user is using the supported kotlin and java versions.
@vojtechhabarta
Copy link
Owner

Hello @Nthalk, I checked your PR and I like the idea of using sealed classes for tagged unions instead of @JsonSubTypes. However your implementation only works for classes declared inside tagged union root class while ObjectMapper could be able to handle subclasses declared anywhere. So in c716d4f I implemented this feature by getting list of subclasses directly from Jackson which can be configured with appropriate module for handling sealed classes.

I understand your use case of one-shot generator but I see value in generating TypeScript code corresponding as much as possible to runtime behaviour of ObjectMapper (with added modules). For your use case you just need to add Jackson module handling sealed classes.

@vojtechhabarta
Copy link
Owner

Here is an example of tagged union defined using Kotlin sealed class:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
// @JsonSubTypes(
//     JsonSubTypes.Type(Rectangle::class),
//     JsonSubTypes.Type(Circle::class),
// )
sealed class Shape {
}

@JsonTypeName("rectangle")
class Rectangle(val a: Int, val b: Int) : Shape() {
}

@JsonTypeName("circle")
class Circle(val radius: Int) : Shape() {
}

It is needed to add com.fasterxml.jackson.module.kotlin.KotlinModule to typescript-generator configuration parameter jackson2Modules.

In this case typescript-generator recognizes tagged union root class by @JsonTypeInfo annotation and there is no need for @JsonSubTypes.

For Java it is similar but currently there is no publicly available Jackson module for Java sealed classes. You can check example of such module in c716d4f#diff-58156e5b6e0095f0b6f2173780b20ec0d7474cfca48257a44c68da1d75a0ef54, unfortunately it is commented out because typescript-generator build needs to run on Java 11.

@Nthalk
Copy link
Author

Nthalk commented Mar 14, 2023

Awesome, I'll close this PR out then. When can we expect the next release? =D

@Nthalk Nthalk closed this Mar 14, 2023
@vojtechhabarta
Copy link
Owner

Just released as part of 3.2.1263.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants