Как исправить "Do not know how to serialize a BigInt" при вызове JSON.stringify

TLDR: поправить прототип:

// Typescript
;(BigInt.prototype as any).toJSON = function () {
  return this.toString()
}
// JavaScript
BigInt.prototype.toJSON = function () {
  return this.toString()
}

Если вы сталкиваетесь с типом BigInt, например как я когда работаю с prisma orm, то в некоторый момент при попытке сериализации объкта, содержащий инстанс BigInt получите ошибку, описанную в заголовке поста.

Давно мы не лазили нашими потными ручками в красивые стандартные прототипы. Я крайне удивлен что такие махникации все еще нужны в 2024. Более углубленные в вопросы стандарта и рабочих групп смогут дать вполне логическое объяснение почему так (мне интересно узнать для общего развития).

Может это не самое лучшее решение? Может у кого есть идеи получше? Пока что оставляю в своем коде вот такую загогулину.

Наскільки зрозумів, це зроблено для зворотної сумісності, щоб у старих програмах нічого не зламалось

Тут була дискусія з цього приводу

Проте пропозиція щодо внесення підтримки BigInt у стандарт вже розглядається і знаходиться на 3-й стадіі

Щодо реалізації я б ще додав підтримку парсингу:

const replacer = (key, value) =>
  typeof value === "bigint" ? `${value}n` : value;

const reviver = (key, value) =>
    /(-?\d+)n/.test(value) ? BigInt(value.replace('n', '')) : value;

const data = {
  number: 1,
  big: 18014398509481982n,
};
const stringified = JSON.stringify(data, replacer);

console.log(stringified);
// {"number":1,"big":"18014398509481982n"}


const parsed = JSON.parse(stringified, reviver);

console.log(parsed);
// {number: 1, big: 18014398509481982n}
1 лайк

Шикарно. Вельмидюкую за всеохоплююче пояснення. Як завжди буває: на всю незручність використовування є гарна причина.