Skip to content

Improve docs for non-default data types #259

@jasongerbes

Description

@jasongerbes

The superjson README provides a recipe for registering a custom transformer for a non-default data type:

import { Decimal } from "decimal.js"

SuperJSON.registerCustom<Decimal, string>(
  {
    isApplicable: (v): v is Decimal => Decimal.isDecimal(v),
    serialize: v => v.toJSON(),
    deserialize: v => new Decimal(v),
  },
  'decimal.js'
);

However, the docs don't include any details about the registerClass and registerSymbol methods, nor do they include details about how a custom transformer can leverage the built-in transformers.

For example, given a CustomMap class the extends the built-in Map class and adds a customProperty and overridden get method, how can I use registerClass or registerCustom in a way that leverages the built-in serialization of the Map's entires?

class CustomMap<K, V> extends Map<K, V> {
  public customProperty: string;

  public constructor(
    customProperty: string,
    entries?: ReadonlyArray<readonly [K, V]> | null
  ) {
    super(entries);
    this.customProperty = customProperty;
  }

  public override get(key: K): V {
    const value = super.get(key);
    if (!value) {
      throw new Error(`Value with key ${key} does not exist.`);
    }
    return value;
  }
}

Using registerClass(CustomMap) doesn't serialize the CustomMap entries:

import SuperJSON from "superjson";
SuperJSON.registerClass(CustomMap);

const map = new CustomMap([
  ["a", 1],
  ["b", 2],
]);

const { json, meta } = SuperJSON.serialize(map);

/*
json = {
  customProperty: "My Map"
};
meta = {
  values: [
    ["class", "CustomMap"]
  ]
};
*/

Using registerCustom, it's unclear how you can leverage SuperJson's built-in Map transformer to serialize and deserialize the CustomMap class:

SuperJSON.registerCustom<CustomMap<any, any>, string>(
  {
    isApplicable: (v): v is CustomMap<any, any> => v instanceof CustomMap,
    serialize: (v) => "", // TODO
    deserialize: (v) => new CustomMap(/* TODO */),
  },
  "CustomMap"
);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions