Skip to content

Instantly share code, notes, and snippets.

@abozhilov
Created November 6, 2022 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abozhilov/117386a562524b32a66985d843cb4936 to your computer and use it in GitHub Desktop.
Save abozhilov/117386a562524b32a66985d843cb4936 to your computer and use it in GitHub Desktop.
JSON custom types serialization/parsing
const OBJECT_TYPE = '[object Object]';
const TYPE_PROP = '__type__';
const VALUE_PROP = '__value__';
const jsParseMap = {
'[object BigInt]': BigInt,
};
const jsSerializeMap = {
'[object BigInt]': (v) => `${v}`,
};
const isTypedObject = (v) => {
const typeTag = {}.toString.call(v);
return (
typeTag === OBJECT_TYPE
&& TYPE_PROP in v
&& VALUE_PROP in v
);
};
const replacer = (_, v) => {
const typeTag = {}.toString.call(v);
if (typeTag in jsSerializeMap) {
return {
[TYPE_PROP]: typeTag,
[VALUE_PROP]: jsSerializeMap[typeTag](v),
};
}
return v;
};
const reviver = (_, v) => {
if (isTypedObject(v)) {
return jsParseMap[v[TYPE_PROP]](v[VALUE_PROP]);
}
return v;
};
// Example
const obj = {
foo: 20n,
};
const jsonStr = JSON.stringify(obj, replacer); // {"foo":{"__type__":"[object BigInt]","__value__":"20"}}
typeof JSON.parse(jsonStr, reviver).foo // bigint;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment