【JavaScript】JSONでBigInt型を無理やり扱う方法

更新日:2024/03/21

BigInt型の値をJSON変換するとエラーになります。
仕様なので仕方がないのですが、どうしてもBigInt型を変換したいケースがあるかもしれません。
そこで無理やりですが、JSONでBigInt型を扱う方法を紹介します。

 

BigInt型をJSON変換するとエラー

JSON.stringify()を使って、BigInt型をJSONに変換すると TypeError がスローされます。

const obj = {
  a:100n
};
const json = JSON.stringify(obj); // TypeError

 

BigInt型をJSON変換する方法

JSON.stringify()は、第二引数で値を置き換えるコールバック関数を指定できます。
この関数でBigInt型ではなくて別の型を返すと、エラーになりません。

そこで、今回は数値の後に "n" を連結した文字列を返します。

const obj = {
  a:12345678901234567890n
};

const json = JSON.stringify(obj,(key,value)=>{
    if( typeof value === "bigint" ) return value+"n";
    return value;
  });
console.log( json ); // {"a":"12345678901234567890n"}

これで TypeError を回避できましたが、受け取り側は "12345678901234567890n" という文字列として解釈されます。
そのため、デコード後に文字列をBigInt型に変換する必要があります。

一般的にはプロパティの型が決まっていることが多いので、個別にBigInt型に変換する方式で大丈夫だと思います。

ただし文字列からBigInt型に変換する方法が無いので、数値に変換してからBigInt型に変換します。
そして、JavaScriptの数値は浮動小数点形式なのも問題です。
桁数の多い整数文字列を数値に変換すると桁あふれで、上手く変換できません。
そこで上位桁から一文字ずつ取得して10倍していきます。

const obj2 = JSON.parse( json );
obj2.a =  [...obj2.a.split( "n" )[0]].reduce(
    ( result , v )=>result * 10n + BigInt( Number( v ) ),
    0n);

console.log( obj2 ); // { a: 12345678901234567890n }

プロパティの型が決まっていないときは、JSON.parse()の第二引数で値の置き換えをします。

const obj2 = JSON.parse( json ,
  (key,value)=>/^\d+n$/.test( value ) ? 
        [...value.split( "n" )[0]]
          .reduce(
            ( result , v )=>result * 10n + BigInt( Number( v ) ),
          0n) :
        value
);
console.log( obj2 ); // { a: 12345678901234567890n }

上手く変換できました。

更新日:2024/03/21

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。