I am trying to use Kotlin serialization (Kotlin 1.7.2, kotlinx.serialization 1.4.1) for value classes that implement a sealed interface:
@Serializable
sealed interface Power {
val value: Int
}
@Serializable
@JvmInline
value class PowerWatt(override val value: Int) : Power
@Serializable
@JvmInline
value class PowerHp(override val value: Int) : Power
When attempting serialization to Json, like so:
@Test
fun `Correctly serialize and deserialize a value class that implements a sealed interface`() {
val power: Power = PowerWatt(123)
val powerSerialized = Json.encodeToString(power)
val powerDeserialized = Json.decodeFromString<Power>(powerSerialized)
assertEquals(power, powerDeserialized)
}
I run into the following error:
kotlinx.serialization.json.internal.JsonDecodingException: Expected class kotlinx.serialization.json.JsonObject as the serialized body of Power, but had class kotlinx.serialization.json.JsonLiteral
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:94)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:81)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:95)
How to make this work? Am I missing something?
The answer was provided in a Kotlin Serialization GitHub Issue here. For value classes, the wrapped underlying type is serialized directly. Hence, there is not wrapping JSON object where the
type
field for the polymorphic serializer could be inserted.