typestack / class-transformer

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

fix: `@Expose` with same name not evaluated for all properties #1503

Open JeffreyArt1 opened 1 year ago

JeffreyArt1 commented 1 year ago

Description

I have noticed that when using the @Expose decorator with the same name for multiple properties in the same class, the transform function is only evaluated for the first property.

For example, consider the following code:

const plain = {
  name: {
    first: 'John',
    last: 'Doe',
  },
};

@Exclude()
class Person {
  @Expose({ name: 'name' })
  @Transform(({ value }) => value.first)
  firstName: string;

  @Expose({ name: 'name' })
  @Transform(({ value }) => value.last)
  lastName: string;
}

Here's a snippet

Expected behavior

console.log(plainToClass(Person, plain)); // Person { firstName: "John", lastName: "Doe" }

Actual behavior

console.log(plainToClass(Person, plain)); // Person { firstName: "John" }

When plainToClass is called with this class and a plain object, only the transform function for the firstName property is evaluated, while the lastName property remains undefined.

I believe this is a bug in the class-transformer library, as both properties should be transformed based on their respective transform functions. Correct me if i'm wrong.

amrsalama commented 11 months ago

@JeffreyArt1 I have the same issue, my workaround is

const plain = {
  name: {
    first: 'John',
    last: 'Doe',
  },
};

@Exclude()
class Person {
  @Expose()
  @Transform(({ obj }) => obj.name.first)
  firstName: string;

  @Expose()
  @Transform(({ obj }) => obj.name.last)
  lastName: string;
}