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 - це ідентифікатор, а не число: арифметика над ним не потрібна, тож рядок - природний тип.