gpt4 book ai didi

Serialization and deserialization in Typescript for classes with nested maps(具有嵌套映射的类的类型脚本中的序列化和反序列化)

转载 作者:bug小助手 更新时间:2023-10-25 17:33:28 29 4
gpt4 key购买 nike



I have some Typescript code I would like to use as NodeJS, which includes simple classes that have fields that are Map's with of objects. I am trying to use the package class-transformer to serialize and deserialize (to JSON and from JSON) my classes, and I am not finding a solution.

我有一些打字代码,我想用作NodeJS,其中包括一些简单的类,这些类的字段是Map的对象。我正在尝试使用包类转换器来序列化和反序列化(到JSON和从JSON)我的类,但我没有找到解决方案。


In addition the "created" field of the parent class is also NOT transformed into Date.

此外,父类的“Created”字段也不会转换为Date。


The documentation is not updated, or does not seem to work.

文档未更新,或似乎不起作用。


Here is a examples of the classes:

以下是这些类的示例:


// Type to be used for Unique Identifiers (UID).
export type Uid = string;

export class UidObject {
// Unique identifier of the object.
readonly uid: Uid;

constructor(uid: Uid) {
this.uid = uid;
}
}

export class TimeStampedObject extends UidObject {
@Type(() => Date)
readonly created: Date;

constructor(uid: Uid, created: Date) {
super(uid);
this.created = created;
}
}

export class Profile extends TimeStampedObject {

/// User display alias.
readonly alias: string;

constructor(
uid: Uid,
created: Date,
alias: string,
) {
super(uid, created);
this.alias = alias;
}
}

export class Group extends UidObject {

readonly name: string;

@Type(() => Map) // What should be used here?
readonly profiles: Map<string, Profile>;

constructor(
uid: Uid,
name: string,
profiles: Map<string, Profile>,
) {
super(uid);
this.name = name;
this.profiles = profiles;
}
}

Using the "class-transformer" functions does not seem to convert the "profiles" field into a Map<Uid, Profile> but just to Map<string, any>.

使用“类转换器”函数似乎不会将“PROFILES”字段转换为Map ,而只是将其转换为Map<字符串,Any>。


let profiles = new Map();
profiles.set("uid-prof-1", new Profile("uid-prof-1", new Date(), "alias-prof-1"));
profiles.set("uid-prof-2", new Profile("uid-prof-2", new Date(), "alias-prof-2"));

let group = new Group("uid-coco", "Coco", profiles);

let json = instanceToPlain<Group>(group);
let instance = plainToInstance<Group, any>(Group, json);

console.log(group);
console.log("------ After =>");
console.log(instance); // This shows an objets which is not in the correct format.
console.log("-----------");
console.log(instance == group); // This returns false

更多回答

The docs describe this case with @Type(() => Skill) skills: Set<Skill>;. Does that solution not work for you?

文档使用@Type(()=>Sills)Skills:Set;来描述这种情况。这个解决方案对你不起作用吗?

I works almost as inteded for Set (it creates an array and not a Set when transforming back). However it does not work at all for Map, instead of creating a Map it just creates a Profile and puts inside a key-value entries which are not objects corresponding to the data of the profiles.

我对set的工作几乎是整型的(它在转换回时创建一个数组,而不是一个set)。然而,它对Map根本不起作用,而不是创建一个Map,它只创建一个配置文件,并将不是与配置文件数据相对应的对象的键值条目放入其中。

优秀答案推荐

@pcba-dev did you find an answer? I have something the like this problem.

@PCBA-dev你找到答案了吗?我有一些类似这个问题的东西。


 @Type(() => MyMapsClass)

creates a map in the result that is typed MyMapsClass, not Map<string, MyMapsClass>

在结果中创建类型为MyMapsClass,而不是Map<字符串,MyMapsClass>的地图


I cant leave a comment due to the lack of reputation so I am posting as an answer, which this is this not. This is what I have come to as a work around, with the hope the someone with more knowledge than a newbie like me will post a correct approach.

我不能留下评论,因为缺乏声誉,所以我张贴作为回答,这是不是。这就是我所做的工作,希望比我这样的新手更有知识的人会发布一个正确的方法。


The code below

下面的代码



  • Uses deserialize to create the result

  • Overwrites the maps from this result with corrected maps

  • Uses Object.assign() to set the values of new, "corrected" instances from the original

  • Marks the map in the class with @Type(() => Map<string, MyMapsClass>), not Type(() => MyMapsClass) which is as I read the docs


    // could not get deserialize to work, this is temp work around
let result = deserialize(MyObject, jsonString!);
let correctedMap = new Map<string, MyMapsClass> ();
for (let [key, value] of result.resultsMap) {
let correctMyMapClass = new MyMapsClass();
Object.assign(correctMyMapClass, value)
correctedNodeMap.set(key, correctMyMapClass);
}
result.MyMapsClass = correctedMap;

更多回答

I was not able to find a solution. I finally decided to include in all my classes toJson() and fromJson methods which are then implemented case by case. It is an overkill, but at least using Github Copilot or ChatGPT the coding time is reduced.

我没能找到解决办法。最后,我决定在我的所有类中包含toJson()和from Json方法,然后逐个实现它们。这是一种夸张的做法,但至少使用Github Copilot或ChatGPT可以减少编码时间。

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com