我在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.stringfy((屈服于字符串,并且我可以通过重写toJSON((并跟踪内部字符串变量来实现这一点。
然而,我想做MyJSON.stringify()
,它封装JSON.stringify((并将MyInt64的字符串值转换为数字。
澄清
export interface IUser {
id: MyInt64;
name: string;
balance: number;
}
const user : IUser = {
id: new MyInt64("9223372036854775807"),
name: "Alice",
balance: 123
};
// normal framework serialization & deserialization
const userString1 = JSON.stringify(user);
// This is expected to be {"id":"9223372036854775807","name":"Alice","balance":123}
const userStringCustom = JSON.stringify(user, (k, v) => {
if (value instanceof MyInt64) {
// call JSONBig.stringify(value) using json-bingint lib
}
});
// This is expected to be {"id":9223372036854775807,"name":"Alice","balance":123}
一个简单的方法是:
toJSON() {
return { val: this._internal.toString() };
}
您可能希望包含某种类型的标识符,以便在反序列化时可以将这些对象与序列化为{val: "some_string_which_may_be_numeric"}
的其他对象区分开来。
如果您的BigInt很大(比如说,数百或数千位(,您可以通过使用十六进制字符串来提高性能(因为内部二进制数表示和十六进制字符串之间的转换既简单又快速,而二进制数和十进制字符串之间的转换是昂贵的计算工作(。基于你的类名";MyInt64";我猜,对于你的情况来说,这种差异是无法衡量的;我在这里提到这个想法是为了完整性和未来的读者。
综合起来,这会产生类似于:
toJSON() {
return {
type: "MyInt64",
val: "0x" + this._internal.toString(16),
};
}
对于反序列化,可以使用reviver函数,类似于:
JSON.parse(..., (key, value) => {
if (typeof value === "object" && value.type === "MyInt64") {
return new MyInt64(value.val);
}
// Optionally handle other special cases here...
return value;
}