I have a class `Foo<Self>` and `Foo#seriali...
# serialization
e
I have a class
Foo<Self>
and
Foo#serializer: KSerializer<Self>
, but when I try to serialize it, it says: Star projection isn't allowed, so instead of
Copy code
abstract class Foo<Self: Foo<Self>> {
    abstract val serializer: KSerializer<Self>
}

@OptIn(ExperimentalSerializationApi::class)
val module = SerializersModule {
    polymorphicDefaultSerializer(Foo::class) {
        it.serializer as KSerializer<Foo>
    }
}
I have to do
Copy code
abstract class Foo<Self: Foo<Self>>: SerializableFoo {
    abstract val serializer: KSerializer<Self>

    override val s
        get() = serializer
}

interface SerializableFoo {
    val s: KSerializer<*>
}

@OptIn(ExperimentalSerializationApi::class)
val module = SerializersModule {
    polymorphicDefaultSerializer(SerializableFoo::class) {
        it.s as KSerializer<SerializableFoo>
    }
}
And always call
Copy code
Json.encodeToString<SerializableFoo>(foo)
Which is much less clean, is there a workaround to tell it to ignore the <*> and "just move on"?
also it seems very unusual to have
serializer
on each instance… how could deserialization possibly work
you can get around the module with
Copy code
abstract class Foo<Self : Foo<Self>> {
    abstract val serializer: KSerializer<Self>

    @ExperimentalSerializationApi
    @InternalSerializationApi
    object Serializer : SerializationStrategy<Foo<*>> {
        override val descriptor: SerialDescriptor =
            buildSerialDescriptor(Foo::class.qualifiedName!!, PolymorphicKind.OPEN)

        @Suppress("UNCHECKED_CAST")
        override fun serialize(encoder: Encoder, value: Foo<*>) {
            encoder.encodeSerializableValue(value.serializer as SerializationStrategy<Foo<*>>, value)
        }
    }
}

@Serializable
class FooImpl : Foo<FooImpl>() {
    override val serializer: KSerializer<FooImpl>
        get() = serializer()
}

@OptIn(ExperimentalSerializationApi::class, InternalSerializationApi::class)
fun main() {
    println(Json.encodeToString(Foo.Serializer, FooImpl()))
}