3

Serializing a generic class with kotlinx.serialization succeeds in JVM but fails in JavaScript with message TypeError: tmp$.serializer is not a function. Please, see the following Unit Test.

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlin.test.Test

@Serializable
data class SerializationTest<T>(val myValue: T)

@Serializable
data class A(val st : SerializationTest<Int>)

class SerializationTests {
    @Test
    fun serializeWithKotlinx() {
        // Succeeds in JVM but throws in JavaScript with "TypeError: tmp$.serializer is not a function"
        Json.encodeToString(SerializationTest(3))
    }

    @Test
    fun serializeWithKotlinxWithBox() {
        // Succeeds always
        Json.encodeToString(A(SerializationTest(3))) 
    }
}

How can I serialize a generic class in JavaScript?

aSemy
  • 5,485
  • 2
  • 25
  • 51
Jordi
  • 2,055
  • 1
  • 16
  • 34

2 Answers2

2

See the docs here

Please note that this example works only on JVM because of serializer function restrictions. For JS and Native, explicit serializer should be used: format.encodeToString(PolymorphicSerializer(Project::class), data) You can keep track of this issue here.

In your case, this code:

Json.encodeToString(SerializationTest(3))`

uses generics, which is only available on JVM.

You'll have to manually pass the serializer to encodeToString(...)

@Test
fun serializeWithKotlinx() {
  val encoded =
    Json.encodeToString(
      SerializationTest.serializer(Int.serializer()),
      SerializationTest(3),
    )
  println(encoded)
}

Or use a SerializersModule (documented here):

@Test
fun serializeWithKotlinxSerializersModule() {

  val module = SerializersModule {
    contextual(SerializationTest::class) { args -> 
      SerializationTest.serializer(args[0]) 
    }
  }

  val mapper = Json { serializersModule = module }

  val encoded = mapper.encodeToString(
    SerializationTest(3),
  )
  println(encoded)
}
aSemy
  • 5,485
  • 2
  • 25
  • 51
1

As per this GitHub issue:

Unfortunately, this is a known problem and we do not support JS legacy anymore. Please use IR backend if possible

With JS IR it works well, giving the same results as JVM.

Jordi
  • 2,055
  • 1
  • 16
  • 34