哈Ha! 我想与您分享将JSON对象反序列化为类的库,该库还可以按类型自动验证输入数据。
不久之前,JavaScript中出现了类的奇妙事物,从而大大简化了编写代码的过程。 但不幸的是,没有出现将JSON反序列化为这些相同类的功能,即 您可以将一个类序列化为一个字符串,但可以自己返回。 为了解决此缺陷,我编写了
ts可序列化库,希望与您分享。
以下代码显示了问题的实质:
export class User { public firstName: string = ""; public lastName: string = ""; public birthDate: Date = new Date(); public getFullName(): string { return [this.firstName, this.lastName].join(' '); } public getAge(): number { return new Date().getFullYear() - this.birthDate.getFullYear(); } } const ivan = new User(); ivan.getFullName();
新伊凡(Ivan)错误的原因是什么? 事实是JSON.parse方法不会反序列化到User类,而是反序列化到Object类,而Object类根本没有getFullName和getAge方法。
我的库如何帮助解决此问题并在User(而不是Object)中反序列化? 只需稍微修改一下代码就足够了:
import { jsonProperty, Serializable } from "ts-serializable"; export class User extends Serializable { @jsonProperty(String) public firstName: string = ""; @jsonProperty(String) public lastName: string = ""; @jsonProperty(Date) public birthDate: Date = new Date(); public getFullName(): string { return [this.firstName, this.lastName].join(' '); } public getAge(): number { return new Date().getFullYear() - this.birthDate.getFullYear(); } } const ivan = new User(); ivan.getFullName(); // ivan.getAge(); // ivan instanceof User; // const text = JSON.stringify(ivan); // const newIvan = new User().fromJson(JSON.parse(text)); // User newIvan.getFullName(); // newIvan.getAge(); // newIvan instanceof User; //
一切都非常简单。 我们从Serializable类继承我们的类,该类具有两个用于反序列化的fromJson方法和用于序列化的toJSON,并且使用允许从JSON接受的属性挂起@jsonProperty装饰器。 无效的数据将被忽略,将向控制台发出警告,并且默认值将保留在属性中。
基本上就是这样。 现在在最前面,您可以像使用C#,Java和其他语言一样轻松地反序列化和序列化。 基于Newtonsoft Json.NET的行为。
常见问题
为什么要继承Serializable?为了向模型添加两个fromJson和toJSON方法。 您可以通过装饰器或猴子修补进行相同的操作。 但是对于Typescript而言,继承是一种更合适的方法。
数据验证如何进行在装饰器中,您必须分配一个允许从JSON接受的数据类型的构造函数。 布尔,字符串,数字对象将分别返回布尔,字符串,数字。 如果需要接受一个数组,则该类型由数组的方括号括起来,例如@jsonProperty([String])。 如果构造函数是从Serializable类继承的,则它也将反序列化到该类中,否则,将返回该对象。
如何捕捉验证错误?默认情况下,该库仅向控制台写入有关验证错误的警告。 要覆盖此行为(例如引发异常或记录到后端),必须覆盖模型的onWrongType方法。
奖金1.深复制。
const user1 = new Uesr(); const user2 = new User().fromJson(user1);
奖励2.懒惰的ViewModels。
如果您需要使用其他数据(例如,用于视图的数据)创建模型,但后端不接受,则可以简单地使用新属性扩展模型,并使用@jsonIgnore装饰器标记这些属性。 然后这些属性将不会被序列化。
import { jsonProperty, Serializable } from "ts-serializable"; export class User extends Serializable { @jsonProperty(String) public firstName: string = ""; @jsonIgnore() public isExpanded: boolean = false; } JSON.stringify(new User());