I’m running into an issue with deserializing a gen...
# serialization
p
I’m running into an issue with deserializing a generic class with a sealed interface as its type parameter
Copy code
@Serializable(with = OptionalSerializer::class)
sealed interface ApiOptional<out T> {
    object None : ApiOptional<Nothing>
    data class Some<T>(val value: T) : ApiOptional<T>
}

open class OptionalSerializer<T>(private val valueSerializer: KSerializer<T>) : KSerializer<ApiOptional<T>> {
    override val descriptor = valueSerializer.descriptor

    override fun serialize(encoder: Encoder, value: ApiOptional<T>) {
        when (value) {
            is ApiOptional.None -> throw SerializationException()
            is ApiOptional.Some -> valueSerializer.serialize(encoder, value.value)
        }
    }

    override fun deserialize(decoder: Decoder): ApiOptional<T> {
        return ApiOptional.Some(valueSerializer.deserialize(decoder))
    }
}
When I try to run this test, it expects a JSON array instead of an object and I’m confused as to why
Copy code
@Serializable
private data class ThisClassCantBeDeserialized(
    val value: ApiOptional<MySealedInterface> = ApiOptional.None,
)

@Serializable
sealed interface MySealedInterface {
    @SerialName("MySealedType")
    @Serializable
    data class MySealedType(
        val sealedValue: String,
    ) : MySealedInterface
}

@Test
fun `test deserialize`() {
    val json = Json {
        ignoreUnknownKeys = true
        explicitNulls = true
        coerceInputValues = true
        encodeDefaults = true
    }

    val result = json.decodeFromString(
        ThisClassCantBeDeserialized.serializer(),
        """
        {
          "value": {
            "type": "MySealedType",
            "sealedValue": "test"
          }
        }
        """.trimIndent(),
    )
}
Error:
Copy code
Unexpected JSON token at offset 12: Expected start of the array '[', but had ' ' instead at path: $.value
JSON input: {
  "value": {
    "type": "MySealedType",
    "sealedValue": "test"
  }
}
Also when encoding, the encoded object is an array
{"value":["MySealedType",{"sealedValue":"test"}]}
but I can’t figure out why its not an object
Nvm, figured it out: It was an issue with the OptionalSerializer where
deserialize/serialize
should have been
return ApiOptional.Some(decoder.decodeSerializableValue(valueSerializer))