Kotlin serialization of value class that implements a sealed interface

1.1k views Asked by At

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?

1

There are 1 answers

0
Ulrich Schuster On BEST ANSWER

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.