Issue with `Schema.Class` Serialization in TanStack with Effect Typescript Library

I am running into an issue wherein
Schema.Class
instances are not serialisable across boundaries at the last stretch when used with TanStack Start, but
Schema.Struct
is. Do note, that this error happens only on TanStacks side - here's a short diagram to summarise the current flow:
DomainEntity (Schema.Class)
  ↓ mapped in Effect backend before sending via HttpApi to client
ViewModel (Schema.Class)
  ↓ works fine
TanStack server-side code receives ViewModel (Schema.Class)
  ↓ serialisation for client on TanStack's end fails unless using Schema.Struct
TanStack client-side code tries to receive fetched data

To understand the details, I want to understand the differences on Effect's side first. The code I'm using to set up the issue is this:
class ViewModel extends Schema.Class<ViewModel>('ViewModel')({}) {}

const effect = Effect.gen(function* () {
    const viewModel = ViewModel.make({})
    return yield* Effect.succeed(viewModel)
})

const fetchViewModel = createServerFn().handler(async () => {
    return Effect.runPromise(effect)
})

export const Route = createFileRoute('/')({
    loader: async ({ context }) => ({ effect: await fetchViewModel() }),
    component: RouteComponent,
})

When invoking fetchViewModel during the initial load the following error happens:
Error reading routerStream: g [Error]: The value [object Object] of type "object" cannot be parsed/serialized.

This is fixed if I make
ViewModel
a
Schema.Struct
instead rather than a class. I suppose the main difference are some added properties that are not serialisable.

Switching to a struct has one smaller aesthetic drawback, as its type will be expanded to Effect<{}> or whatever it is while Classes typically reference their proper name such as Effect<ViewModel>. What other differences should I keep in mind if I'm forced to make the data types I send across the boundary structs instead.
Was this page helpful?