🔢

TypeScriptのBigIntをJSONに変換できない、なぜ。

2024/12/11に公開

はじめに

筆者はTypeScriptを最近学習中です。
JavaScriptは業務でなんとなく使ったことがある程度で、モダンなフロントエンドの技術はほぼ触れたことがありません。

本記事はTypeScriptのBigInt型とそのシリアライズについて、気になったことがあったので自身の調べた経緯と一旦の結論を書き出してます。
BigInt型とはnumber型を超えてとても大きな数を表すことができる型です。

背景

最近サバイバルTypeScriptでTypeScriptを学習しています。
BigInt(型)のページを読んでいる時でした。


BigInt型をJSON文字列に変換しようとしたときにエラーが出ると書かれています。

気になったのはここです。

TypeError: Do not know how to serialize a BigInt

(なんでシリアライズできない?)
と思ったので色々調べてみました。

そもそもシリアライズって何?

https://e-words.jp/w/シリアライズ.html

シリアライズ(serialize)とは、複数の要素を一列に並べる操作や処理のこと。単にシリアライズといった場合には、プログラムの実行状態や複雑なデータ構造などを一つの文字列やバイト列で表現する「直列化」を指すことが多い。

データを送ったり保存したりするときにやりますよね。
JSON.stringifyは文字通りJSON文字列に変換するわけです。
シリアライズです。

なぜBigInt型の値をJSON.stringifyできない?

本題です。

MDNのドキュメント、BigIntの記事にて
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/BigInt#json_での使用

BigInt 値は既定で JSON のシリアライズに対応していないためです。

ふむ、ですよね。対応してないからエラーが出るのはわかりました。
その「対応してない」って部分を掘り下げてみたいと思います。(対応させない理由がある?)

JSONの標準仕様がBigIntをサポートしていない

JSONの標準仕様に書かれています。

数値はIEEE 754の倍精度浮動小数点数(Number)に限定されています。
BigIntのような任意精度の整数型は、仕様上定義されていません。
JSONで扱える数値は64ビット(8バイト)を使用しますが、BigIntはそれを遥かに超えてメモリを占有する可能性があります。

それでもシリアライズしようと思えばできることはできます。
例として先にNumber型にキャストするというシンプルな方法が載っています。

If you can alter the data source, avoid using BigInt values and cast it to a number first (which may lose precision for large numbers).

ただしNumber型の範囲外の値は正しくキャストできないので精度を欠く可能性があります。

こういった背景から暗黙的には変換ができないのでエラーを出すようにしていると理解しました。

おわりに

「JSON.stringifyがBigInt型に対応していないから」というだけなんですが、調べる中でただの数値型に関しても知らないことがたくさんありました。
業務や学習を行う中で何かふとした疑問を満足したところから一歩深く調べることが自分自身の持っている知識を増やすいいきっかけになるのかなと感じました。
みなさんもよければ、ふとした疑問をほんの少し深く調べてみると良いことがあるかもしれません!!

BABY JOB  テックブログ

Discussion