Обратимая сериализация BigInt

Недавно мне пришлось выполнить небольшой сериализованный обмен JSON между клиентом и сервером, и изначально у меня возникли некоторые проблемы с расширением данных с помощью нового типа BigInt, потому что стандартному JSON.stringify он не нравится, вызывая эту ошибку:

TypeError: Do not know how to serialize a BigInt.

Немного покопавшись, я обнаружил, что очень легко реализовать свою собственную версию JSON.stringify, которая заботится о значениях BigInt:

Однако это создает необратимый JSON, т.е. если я передам его в JSON.parse в клиенте, то для каждого исходного BigInt я получу строку с номером, который, даже если я буду разбирать дальше, я не могу сказать если бы это действительно был BigInt.

Это хорошо известная проблема, если вы посмотрите вокруг, есть обсуждения и некоторые проекты спецификаций, предлагающие решение для этого в будущем.

Но в итоге я получил очень простое решение, показанное ниже, которое отлично работает сегодня, не дожидаясь лучшего дня ...

Или, в качестве альтернативы, вы можете предоставить свою собственную реализацию для официально поддерживаемого сериализатора типа toJSON для BigInt:

Выше мы просто добавляем n в конце каждого числа, что делает его похожим на BigInt в JavaScript, и мы можем легко проанализировать такой формат с помощью RegEx.

А чтобы десериализовать такой JSON, мы можем использовать следующий парсер:

Он работает так же, как JSON.parse, но также возвращает BigInt для каждой строки, соответствующей нашему формату 123n.

И если вас беспокоит, что такой формат, как 123n, может внезапно вступить в конфликт с какой-то случайной строкой, есть способы избежать этого ...

Самый простой - немного запутать формат, например, вместо формата 123n использовать что-то более подробное, например 123 # bigint или подобное, при условии, что сериализатор и де- сериализатор использует тот же формат, он будет работать отлично.

И чтобы сделать его полностью защищенным от ошибок, вы можете подсчитать количество сериализованных значений BigInt, передать счет клиенту, который затем подсчитает количество совпадений с шаблоном, сравнит его со счетчиком и выдаст ошибку, если есть несоответствие. Но для большинства случаев это, наверное, излишество.