Viv*_*not 1 json local-storage typescript
我有一个Typescript应用程序。我将localstorage用于开发目的是为了存储我的对象,而在反序列化时遇到了问题。
我有一个类型为MeetingModel的对象会议:
export interface MeetingModel {
date: moment.Moment; // from the library momentjs
}
Run Code Online (Sandbox Code Playgroud)
我使用将该对象存储在localStorage中JSON.stringify(meeting)。
我假设stringify调用moment.toJson()返回一个iso字符串,因此存储的值是:{"date":"2016-12-26T15:03:54.586Z"}。
检索此对象时,我将执行以下操作:
const stored = window.localStorage.getItem("meeting");
const meeting: MeetingModel = JSON.parse(stored);
Run Code Online (Sandbox Code Playgroud)
问题是:Meeting.date包含一个字符串而不是一刻!
因此,首先我想知道为什么TypeScript会发生这种情况?为什么我可以分配一个字符串值而不是Moment并且编译器同意?
其次,如何将我的对象从纯JSON对象(也称为字符串)还原为Typescript类型?
我当然可以创建一个工厂,但是当我的对象数据库长大时,完成所有这些工作会很麻烦。
也许首先有一个更好地存储在本地存储中的解决方案?
谢谢
1)TypeScript是可选输入的。这意味着有很多方法可以绕过类型系统的严格性。该any类型允许您进行动态键入。如果您知道自己在做什么,这会非常方便,但是您当然也可以用脚射击。
该代码将编译:
var x: string = <any> 1;
Run Code Online (Sandbox Code Playgroud)
这里发生的是将number1强制转换为any,这对TypeScript意味着它只是假设您作为开发人员就知道它是什么以及如何使用它。由于将any类型分配给stringTypeScript是绝对可以的,即使您在运行时可能会出错,就像在编写JavaScript时出错一样。
当然,这是设计使然。TypeScript类型仅在编译时存在。您JSON.parse输入的字符串类型对于TypeScript是未知的,因为输入字符串仅在运行时存在,并且可以是任何东西。因此any类型。TypeScript确实提供了所谓的类型保护。类型防护是在编译时和运行时都可以理解的一些代码,但这超出了您的问题范围(如果您有兴趣,请谷歌搜索)。
2)序列化和反序列化数据通常不像调用JSON.stringify和那样简单JSON.parse。大多数类型信息都丢失给JSON,通常,您在运行时想要在内存中存储对象的方式与您想要存储以进行传输或存储(内存,磁盘或任何其他介质)的方式有很大不同)。例如,在运行时,您可能需要查找表,用户/会话状态,私有字段,特定于库的属性,而在存储中,您可能需要版本号,时间戳,元数据,不同类型的规范化等。JSON.stringify在JavaScript领域中想要的任何东西,但这必然意味着它是一个好主意。您可能需要设计实际存储数据的方式。例如,一个iso字符串看起来很漂亮,但是占用很多字节。如果只有几个没关系,但是当每秒传输数百万时,您可能需要考虑另一种格式。
我的建议是为要保存的对象定义接口,就像.toJson在模型对象上创建一个方法一样,该方法将返回您可以简单地序列化的DTO(数据传输对象)JSON.stringify。然后在返回的过程中,将any输出JSON.parse转换为DTO,然后使用工厂函数或创建的构造函数将其转换回模型。这似乎是很多样板,但根据我的经验,这是完全值得的,因为现在您可以控制要存储的内容,这使您可以灵活地更改模型而不会遇到反序列化问题。
祝好运!
| 归档时间: |
|
| 查看次数: |
897 次 |
| 最近记录: |