Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Навіщо потрібен BigInt і як не втратити точність великих ID з API?

Number точно представляє цілі числа лише до Number.MAX_SAFE_INTEGER = 2^53 - 1 = 9 007 199 254 740 991. Далі сусідні цілі числа вже неможливо розрізнити:

9007199254740993 === 9007199254740992; // true

BigInt - окремий тип цілих чисел довільної довжини:

const big = 9007199254740993n;      // суфікс n
big + 2n;                           // 9007199254740995n
BigInt('123456789012345678901234567890');

Обмеження BigInt: не можна змішувати з Number в арифметиці (1n + 1 - TypeError), Math.* з ним не працює, ділення відкидає дробову частину, а JSON.stringify кидає помилку.

Реальна проблема - ID з бекенду. Twitter/X ID, Snowflake-ідентифікатори, bigint-ключі з бази можуть перевищувати 2^53. JSON.parse перетворює число на Number і тихо спотворює останні цифри:

JSON.parse('{"id": 1234567890123456789}').id; // 1234567890123456800

Запит з таким ID потім шукає не той запис - і помилка проявляється далеко від причини.

Рішення:

  • Віддавати великі ID рядками - найпоширеніший підхід (Twitter API повертає і id, і id_str). У Laravel - каст до рядка в API Resource.
  • JSON.parse з reviver і context.source (нові браузери й Node.js) дає доступ до сирого тексту числа, щоб перетворити його на BigInt.
  • ID - це ідентифікатор, а не число: арифметика над ним не потрібна, тож рядок - природний тип.

Докладніше в документації: BigInt

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання