-
Notifications
You must be signed in to change notification settings - Fork 64
Description
Describe your motivation
(reposted from forum)
I write a lot of code these days using sealed interfaces with record subtypes so you can exhaustively pattern match on them using switch
in newer Java versions - similar to ADTs / Sum Types from Haskell or Rust Enums.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = Bar.class, name = "Bar"),
@JsonSubTypes.Type(value = Baz.class, name = "Baz")}),
sealed interface Foo {
public record Bar(Integer x) implements Foo {};
public record Baz(String y) implements Foo {};
}
I’m trying to send these over to the frontend for use in my Hilla app, and it almost works but there are a few type-generation issues - only the interface for each record is generated, without the @type
discriminator property and they don’t extend the super interface.
Describe the solution you'd like
I'd like types to be generated for each subtype, that include the @type
discriminator, that all extend from a super interface. From there, all endpoints using this type use the supertype, or even use a TypeScript Union type to represent the cases.
There seems to be partial support for subtypes, used as part of the Filter
mechanism, which is quite close but uses a class hierarchy with subtypes rather than a sealed interface with records - but Jackson encodes and works with them exactly the same.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
@Type(value = OrFilter.class, name = "or"),
@Type(value = AndFilter.class, name = "and"),
@Type(value = PropertyStringFilter.class, name = "propertyString") })
public class Filter {
}
Describe alternatives you've considered
I can use sealed classes to approximate this, similar to how Filter
works, but it's not as powerful to use as sealed records which approximate Sum Types well.
I'm considering creating a DTO for each ADT that converts it into a sealed class at the network boundary, as I want to keep using sealed records within the rest of the codebase.
Additional context
There’s an older post at Endpoint Generator and Class Type Generation for Derived Classes in the forum but not much more info.