如何使JSON.parse()对待所有的数字作为BigInt?



我有一些数字在json溢出的数字类型,所以我想要它是bigint,但如何?

{"foo":[[0],[64],[89],[97]],"bar":[[2323866757078990912,144636906343245838,441695983932742154,163402272522524744],[2477006750808014916,78818525534420994],[18577623609266200],[9008333127155712]]}

TLDR;

您可以使用JSON.parse()reviver参数

详细解决方案要以这种方式控制JSON.parse()的行为,您可以使用JSON.parse(reviver)的第二个参数-预处理键值对的函数(并且可能将所需的值传递给BigInt())。

然而,被识别为数字的值仍然会被强制(准确指出这个问题的功劳要归功于@YohanesGultom)。

为了解决这个问题,您可以在源JSON字符串中引用大数(将它们转换为字符串),以便在转换为bigint时保留它们的值。

只要您希望仅将某些数字转换为bigint,您就需要选择适当的标准(例如,检查Number.isSafeInteger()的值是否超过Number.MAX_SAFE_INTEGER,如@PeterSeliger所建议的)。

因此,你的问题可能会解决,像这样:

// source JSON string
const input = `{"foo":[[0],[64],[89],[97]],"bar":[[2323866757078990912,144636906343245838,441695983932742154,163402272522524744],[2477006750808014916,78818525534420994],[18577623609266200],[9008333127155712]]}`

// function that implements desired criteria
// to separate *big numbers* from *small* ones
//
// (works for input parameter num of type number/string)
const isBigNumber = num => !Number.isSafeInteger(+num)

// function that enquotes *big numbers* matching
// desired criteria into double quotes inside
// JSON string
//
// (function checking for *big numbers* may be
// passed as a second parameter for flexibility)
const enquoteBigNumber = (jsonString, bigNumChecker) =>
jsonString
.replaceAll(
/([:s[,]*)(d+)([s,]]*)/g,
(matchingSubstr, prefix, bigNum, suffix) =>
bigNumChecker(bigNum)
? `${prefix}"${bigNum}"${suffix}`
: matchingSubstr
)

// parser that turns matching *big numbers* in
// source JSON string to bigint
const parseWithBigInt = (jsonString, bigNumChecker) =>
JSON.parse(
enquoteBigNumber(jsonString, bigNumChecker),
(key, value) =>
!isNaN(value) && bigNumChecker(value)
? BigInt(value)
: value
)
// resulting output
const output = parseWithBigInt(input, isBigNumber)

console.log("output.foo[1][0]: n", output.foo[1][0], `(type: ${typeof output.foo[1][0]})`)
console.log("output.bar[0][0]: n", output.bar[0][0].toString(), `(type: ${typeof output.bar[0][0]})`)
.as-console-wrapper{min-height: 100% !important;}

注意:你可能会发现RegExp模式在JSON值中匹配数字字符串不是很健壮,所以你可以自由地提出你的(因为我的是我为了演示目的而最快地摘下来的)

注意:你仍然可以选择一些库,就像@YohanesGultom建议的那样,但是为了这个唯一的目的,在你的客户端包中添加10k或者在你的服务器端依赖项中添加37k(可能是docker图像大小)可能不太合理。

你可以试试我的库来解决这个问题:https://www.npmjs.com/package/json-with-bigint

的例子:

import { JSONParse } from 'json-with-bigint';

const yourJSON = `{"someValue":42,"someBigValue":10000000000000000365}`;
JSONParse(yourJSON); // { someValue: 42, someBigValue: 10000000000000000365n }

Library将自动计算BigInt,因此不需要传递具有BigInt值的特定键的列表。

还支持一致的往返操作(parse - stringify - parse)。反序列化的值将与最初序列化的值相同,反之亦然。

import { JSONParse, JSONStringify } from 'json-with-bigint';

const yourJSON = `{"someValue":42,"someBigValue":10000000000000000365}`;
JSONParse(yourJSON); // { someValue: 42, someBigValue: 10000000000000000365n }
JSONStringify(data); // '{"someValue":42,"someBigValue":10000000000000000365}'
JSONParse(JSONStringify(data)); // { someValue: 42, someBigValue: 10000000000000000365n }

相关内容

  • 没有找到相关文章

最新更新