【问题标题】:How to revive TypeScript private properties with getters after serialization?序列化后如何使用 getter 恢复 TypeScript 私有属性?
【发布时间】:2020-12-14 04:13:40
【问题描述】:

我遇到了一个我不知道如何处理的类的序列化问题。

我从 REST 或数据库请求创建对象,如下所示:

export interface ILockerModel {
    id: string
    lockerId: string
    ownerId: string
    modules: IModuleModel[]
}
export class LockerModel implements ILockerModel {
    private _id: string
    private _lockerId: string
    private _ownerId: string
    private _modules: ModuleModel[]

    constructor(document: ILockerModel) {
        this._id = document.id
        this._lockerId = document.lockerId
        this._ownerId = document.ownerId
        this._modules = document.modules.map(m => new ModuleModel(m))
    }
    // Utility methods
}

然后,我有多种实用方法,可以更轻松地使用模型、在列表中添加和删除内容等等。

完成后,我想将对象保存到文档数据库或在 REST 响应中返回,因此我调用 JSON.stringify(objectInstance)。但是,这给了我这个类,但所有属性都加了下划线 (_),而不是我的 getter 值。这会破坏我应用程序其他部分的反序列化。

序列化接口给了我我想要的东西,但我还没有找到从类到接口表示的直接方法。问题变得更加棘手,因为我在层次结构中反序列化数据(请参阅构造函数中的模块映射)。

你通常如何解决这个问题?

【问题讨论】:

标签: javascript json typescript getter


【解决方案1】:

据我所知,您并没有真正实现ILockerModel。这不应该抛出错误吗?

当我运行它时,我得到以下信息:

“LockerModel”类型缺少“ILockerModel”类型的以下属性:id、lockerId、ownerId、modules

另一件事是JSON.strigify() 只是获取您的对象并对其所有属性进行字符串表示。它不关心你的吸气剂。如果你想让它转换成正确的格式,你应该给它一个正确格式的对象。

一种解决方案是使用mapreduce 的组合从所有键中删除“_”:

const input = {
  _test: 123,
  _hello: 'world'
};

console.log(input);
console.log(JSON.stringify(input));

const convertToJson = (obj) => {
  return Object.entries(obj) // Create array from object
    .map(([key, value]) => [  // change key to remove '_'
      key.startsWith('_') ? key.substring(1) : key, 
      value
    ])
    .reduce((acc, [key, value]) => { // Transform back to object
      acc[key] = value;
      return acc;
    }, {});
}

const output = convertToJson(input);


console.log(output);
console.log(JSON.stringify(output));

或者如果你被允许使用 ES10:

const input = {
  _test: 123,
  _hello: 'world'
};

console.log(input);
console.log(JSON.stringify(input));

const convertToJson = (obj) => {
  return Object.fromEntries( // Create Object from array
    Object.entries(obj) // Create array from object
      .map(([key, value]) => [ // change key to remove '_'
        key.startsWith('_') ? key.substring(1) : key, 
        value
      ])
  );
}

const output = convertToJson(input);


console.log(output);
console.log(JSON.stringify(output));

【讨论】:

  • 你不会只创建吸气剂吗?请参阅:stackoverflow.com/a/12850536/1762224,但这更符合您要完成的任务,但对 TS 来说更安全:stackoverflow.com/a/44315652/1762224
  • 接口实现正确,我有最严格的检查。不幸的是,我在 ES 版本中受到限制,因为它在 Azure Functions 中运行。删除下划线的功能看起来是一个足够好的解决方案,我会试一试。谢谢!
猜你喜欢
  • 2018-07-16
  • 2017-11-03
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
相关资源
最近更新 更多