typestack / class-transformer

Decorator-based transformation, serialization, and deserialization between objects and classes.
MIT License
6.78k stars 495 forks source link

Map returns undefined values with never versions #1256

Open driescroons opened 2 years ago

driescroons commented 2 years ago

I've got the following code that I set up for testing purposes:

@Exclude()
class Transformer {
  @Expose()
  @IsString({ each: true })
  public map!: Map<string, string>;
}

const obj = {
  map: new Map([
    ["1", "123"],
    ["2", "123"],
    ["3", "123"]
  ])
};

let data = plainToClass(Transformer, obj);
console.log(data);

Ever since 0.4.1, the values of the map return undefined (after moving to plainToInstance).

The following printscreen is the result of using version 0.4.1: image

The following printscreen is the result of using0.4.0: image

As you can see, the values are not undefined.

Did the syntax of validating a map change? Or is there something wrong? Following link is the CSB for testing: https://codesandbox.io/s/busy-kilby-7e8z73?file=/src/index.ts

patil-milind commented 2 years ago

This same issue is also reproducible in the latest version 0.5.1 for the function plainToInstance.

CodyTseng commented 2 years ago

issue: #596 PR: #374

// ...
if (this.transformationType === TransformationType.PLAIN_TO_CLASS) {
  subValue = value[valueKey];
}
// ...

I don't know why it changed to this 😂.

Maybe the maintainers think plain object should be a simple JSON object. Like this:

@Exclude()
class Transformer {
  @Expose()
  @Type(() => String)
  public map!: Map<string, string>;
}

const obj = {
  map: {
    '1': '123',
    '2': '123',
    '3': '123',
  }
};

const data = plainToInstance(Transformer, obj);
console.log(data);

Output:

Transformer {
  map: Map(3) { '1' => '123', '2' => '123', '3' => '123' }
}
driescroons commented 2 years ago

I was trying to have a map of type Map<string, object[]> with automatically generated docs. I've since then switched back to a regular object to get the proper result. For people running into this issue, this is how I fixed it:

  @Expose()
  @IsObject()
  @JSONSchema({
    type: "object",
    properties: {
      "{id}": {
        type: "array",
        items: {
          $ref: `#/components/schemas/${OtherClassTransformerClass.name}`,
        },
      },
    },
  })
  public collections!: { [key: string]: OtherClassTransformerClass[] };
victor-shelepen commented 1 year ago

It seems the functionality that is described here is not supported. There is a comment with a workaround solution. Nested map?