【问题标题】:Typescript class customize JSON serialization & deserializationTypescript 类自定义 JSON 序列化和反序列化
【发布时间】:2022-09-23 02:53:12
【问题描述】:

我在 TS 中有一个包装类,它接受构造函数中的字符串并在内部转换为 bigint。我想自定义这个类的对象的序列化/反序列化,

export class MyInt64 implements MyDataTypes {
    private readonly _internal: BigInt;

    constructor(val: string) {
        this._internal = BigInt(val);
    }
    toJSON() {
        return {
            val: this._internal,
        };
    }
}

JSON.stringify(new MyInt64(\"9223372036854775807\")) 被调用时,我希望它不要将数字向下舍入到9223372036854776000

这个怎么做?


编辑

对于我的类型MyInt64,我希望 JSON.stringify() 生成字符串,并且我可以通过覆盖 toJSON() 并跟踪内部字符串变量来实现。

但是我想做MyJSON.stringify(),它包装了 JSON.stringify() 并将 MyInt64 的字符串值转换为数字。

  • 嗯,从技术上讲,现在它没有四舍五入。它只是抛出一个错误,因为 BigInt 无法转换为 JSON

标签: javascript json typescript bigint


【解决方案1】:

一种简单的方法是:

  toJSON() {
    return { val: this._internal.toString() };
  }

您可能希望包含某种类型的标识符,以便在反序列化时可以将这些对象与序列化为{val: "some_string_which_may_be_numeric"} 的任何其他对象区分开来。

如果您的 BigInts 很大(比方说,数百或数千位),您可以通过使用十六进制字符串来提高性能(因为内部二进制数表示和十六进制字符串之间的转换简单快捷,而二进制数和十进制字符串之间的转换很昂贵计算工作)。根据您的班级名称“MyInt64”,我猜您的情况无法衡量差异;我在这里提到这个想法是为了完整性和未来的读者。

放在一起,这会给出类似的东西:

  toJSON() {
    return {
      type: "MyInt64",
      val: "0x" + this._internal.toString(16),
    };
  }

对于反序列化,您可以使用reviver function,例如:

JSON.parse(..., (key, value) => {
  if (typeof value === "object" && value.type === "MyInt64") {
    return new MyInt64(value.val);
  }
  // Optionally handle other special cases here...
  return value;
}

【讨论】:

  • 谢谢jmrk。除了修改 toJSON() 方法之外,是否可以自定义 JSON.stringify() ?我编辑了问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 2014-08-02
  • 2018-03-09
  • 2021-05-12
  • 1970-01-01
相关资源
最近更新 更多