JavaScriptのJSON.stringifyでBigIntが含まれるとエラーになる

BigIntが含まれるとエラーになる

JavaScriptではJSONを使用する機会が多いですが、BigInt型をJSONに含めてJSON.stringifyで文字列にするとエラーになるので注意が必要です。

// これはセーフ
const bigIntValue = BigInt(12345678901234567890n)
const obj = {
  value: bigIntValue
}
console.log(obj.value)
// 12345678901234567890n
// これはエラー
const bigIntValue = BigInt(12345678901234567890n)
const obj = {
  value: bigIntValue,
}
console.log(JSON.stringify(obj))
// Uncaught TypeError: Do not know how to serialize a BigInt

JSON.stringifyでエラーを出なくするには

そのままBigInt型を入れるとJSON.stringifyで文字列にするとエラーになるので、typeofで方がbigintか判定して、bigintの場合はtoString()で文字列に変換すればエラーになりません。

const bigIntValue = BigInt(12345678901234567890n)
const obj = {
  value: typeof bigIntValue === 'bigint' ?
    bigIntValue.toString() :
    bigIntValue
}

console.log(JSON.stringify(obj))
// {"value":"12345678901234567890"}

文字列をBigIntに変換するには

BigIntを文字列に変換後は文字列がBigIntだったかどうかの情報は失われるので、BigIntに再変換する場合は「18桁以上の数字か」を判定して一致したらBigIntに変換するようにします。

const bigIntString = '12345678901234567890'
const convertBigInt = (value) => {
  return /^\d{18,}$/.test(value) ?
    BigInt(value) :
    value
}
const result = convertBigInt(bigIntString)
console.log(result)
// 12345678901234567890n

ちなみに文字列の最後にnがあるとBigInt()で変換できなくなります。

const bigIntString = '12345678901234567890n'
console.log(BigInt(bigIntString))
// Uncaught SyntaxError: Cannot convert 12345678901234567890n to a BigInt