flightcontrolhq / superjson

Safely serialize JavaScript expressions to a superset of JSON, which includes Dates, BigInts, and more.
https://www.flightcontrol.dev?ref=superjson
MIT License
4.02k stars 87 forks source link

Registering classes extending Array don't work properly #239

Closed NeilTheFisher closed 1 year ago

NeilTheFisher commented 1 year ago

When serializing a class (after using registerClass) which extends Array, the resulting json is an object containing the keys of an array (0, 1, 2...) rather than actually being an array.

expected: image

actual: image

Seems like the logic to be changed here would be to make sure to create an array if it isArray rather than an object when it's a class.

My quick workaround to this was to stop using registerClass on the class that extends Array so it's serialized as a normal Array; then when deserializing, I use

Object.setPrototypeOf(
  SuperJSON.parse<MyListExtendsArray>(listOfThings),
  MyListExtendsArray.prototype
) as MyListExtendsArray

rather than

Object.assign(Object.create(MyListExtendsArray.prototype), SuperJSON.parse<MyListExtendsArray>(listOfThings))

to convert it back to a class instance or else it goes back to being a regular object instead of an array as shown in the images

Skn0tt commented 1 year ago

Hi @sylent3524, sorry for my late reply!

Have you tried using registerCustom? It allows you to fully customise the de/serialisation, and looks like it might solve your problem. Here's an example: https://github.com/blitz-js/superjson/blob/ae7dbcefe5d3ece5b04be0c6afe6b40f3a44a22a/src/index.test.ts#L520-L543