Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: @Expose decorator exposes class property names when working with Maps #319

Closed
panki opened this issue Dec 19, 2019 · 4 comments · Fixed by #405
Closed

fix: @Expose decorator exposes class property names when working with Maps #319

panki opened this issue Dec 19, 2019 · 4 comments · Fixed by #405
Labels
status: done/released Issue has been completed, no further action is needed.

Comments

@panki
Copy link

panki commented Dec 19, 2019

import 'reflect-metadata';

import { Expose, plainToClass, Type } from 'class-transformer';

export class Skill {
  @Expose() name: string;
}

export class Weapon {
  @Expose() name: string;
  @Expose() range: number;
}

export class Player {
  name: string;

  @Expose()
  @Type(() => Skill)
  skills: Set<Skill>;

  @Expose()
  @Type(() => Weapon)
  weapons: Map<string, Weapon>;
}

const v = {
  name: 'name',
  skills: new Set([
    { name: 'skill1', remove: 1 },
    { name: 'skill2', remove: 2 },
  ]),
  weapons: new Map([
    ['w1', { name: 'weapon1', range: 1, remove: 1 }],
    ['w2', { name: 'weapon2', range: 2, remove: 2 }],
  ]),
};

console.log(
  plainToClass(Player, v, {
    excludeExtraneousValues: true,
  }),
);

Output:

Player {
  skills: [ Skill { name: 'skill1' }, Skill { name: 'skill2' } ],
  weapons: Map { 'name' => undefined, 'range' => undefined }
}

Expected output:

Player {
  skills: [ Skill { name: 'skill1' }, Skill { name: 'skill2' } ],
  weapons: Map {
    'w1' => Weapon { name: 'weapon1', range: 1 },
    'w2' => Weapon { name: 'weapon2', range: 2 }
  }
}
@randfur
Copy link

randfur commented Jul 29, 2020

We are encountering this issue as well. Using @Expose seems to mess up @Type for Map fields and add the inner type's fields to the map.

@cvlvxi
Copy link
Contributor

cvlvxi commented Jul 29, 2020

It appears that when adding @Expose() to the nested class in conjunction with @Type where its tied to a Map<string,T> type does the following

    class Weapon {
      @Expose() name: string;
      @Expose() range: number;
    }

   class Player {
      @Expose() name: string
      @Expose()
      @Type(() => Weapon)
      weapons: Map<string, Weapon>;
    }

    const json = {
      name: "name",
      weapons: {
        "w1": { name: "weapon1", range: 1 },
        "w2": { name: "weapon2", range: 2}
      }
    };

    console.log(
      plainToClass(Player, json, {
        excludeExtraneousValues: false,
      })
    )

Result

    Player {
      name: 'name',
      weapons: Map {
        'w1' => Weapon { name: 'weapon1', range: 1 },
        'w2' => Weapon { name: 'weapon2', range: 2},
        'name' => undefined,
        'range' => undefined
      }
    }
  • You can see that it added the Weapon properties as the string keys of the Map which doesn't seem right..
  • As you can see here:
        'name' => undefined,
        'range' => undefined
  • This is with Expose() added and also excludeExtraneousValues set to false
  • When we set excludeExtraneousValues to true we get the abnormal behaviour that the above users is experiencing
    class Weapon {
      @Expose() name: string;
      @Expose() range: number;
    }

    class Player {
      @Expose() name: string;

      @Expose()
      @Type(() => Weapon)
      weapons: Map<string, Weapon>;
    }

    const json = {
      name: "name",
      weapons: {
        "w1": { name: "weapon1", range: 1 },
        "w2": { name: "weapon2", range: 2}
      }
    };

    console.log(
      plainToClass(Player, json, {
        excludeExtraneousValues: true,
      })
    );
  });

Result

    Player {
      weapons: Map { 'name' => undefined, 'range' => undefined }
    }

@NoNameProvided
Copy link
Member

This has been fixed in develop via #405 and be included in the next release.

@NoNameProvided NoNameProvided changed the title Bug with Map properties with exposed attributes fix: @Expose decorator exposes class property names when working with Maps Aug 7, 2020
@github-actions
Copy link

github-actions bot commented Sep 7, 2020

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 7, 2020
@NoNameProvided NoNameProvided added status: done/released Issue has been completed, no further action is needed. and removed status: fixed Issues with merged PRs, but not released yet labels Jan 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: done/released Issue has been completed, no further action is needed.
Development

Successfully merging a pull request may close this issue.

4 participants