class-transformer: fix: ExposeAll does not work with excludeExtraneousValues

Description

Strategy ‘exposeAll’ does not work as expected with true excludeExtraneousValues flag. Actual behaviour is as all properties were not exposed.

Minimal code-snippet showcasing the problem

class Dog {
  name: string;
}
const plainDoggie = {
      name: 'Azor',
      surname: 'dogs does not have surnames :('
};
const doggie = plainToClass(Dog, plainDoggie, {
      strategy: 'exposeAll',
      excludeExtraneousValues: true
});
console.log('doggie', doggie);
// should be {name:'Azor'}, but is {} instead

StackBlitz example

Expected behavior

All properties are exposed. In above example doggie = {name: ‘Azor’}

Actual behavior

Properties are not exposed. In above example doggie = {}

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 57
  • Comments: 28

Most upvoted comments

strategy: 'exposeAll' is a strategy: it should mean that by default, everything is exposed. excludeExtraneousValues: true means if something outside the class is in the object, then remove it. The combination of these two options should logically be that you don’t need to decorate anything in the class with @Expose because everything will be exposed, but extraneous values should be removed.

Thus, this is a bug.

strategy: 'exposeAll' is a strategy: it should mean that by default, everything is exposed.

excludeExtraneousValues: true means if something outside the class is in the object, then remove it.

The combination of these two options should logically be that you don’t need to decorate anything in the class with @Expose because everything will be exposed, but extraneous values should be removed.

Thus, this is a bug.

Yes! 👍

Same here, is there any solutions for this yet?

you can use @Expose for each property that you wanna expose it

I faced the same issue so I created an extension method to achieve the wanted behavior:

  1. Create a new TypeScript file ‘transform.dto.ts’
import { plainToInstance } from 'class-transformer';
import { getMetadataStorage } from 'class-validator';

export function transformToDto<T>(DtoClass: new () => T, data: any): T {

    const metadataStorage = getMetadataStorage();
    const dtoMetadata = metadataStorage.getTargetValidationMetadatas(DtoClass, '', true, true);

    const dtoInstance = plainToInstance(DtoClass, data);

    // Extract the keys from the DTO class metadata
    const dtoKeys = dtoMetadata.map(meta => meta.propertyName);

    // Filter out fields not in the DTO
    return dtoKeys.reduce((filtered, key) => {
        filtered[key] = dtoInstance[key];
        return filtered;
    }, {} as T);
}
  1. Use it like this:

const myInstance = transformToDto(myDTO, myData);

It has been 2 years and this has yet to be resolved… Why?

Any news on this issue?

Any news on this issue? This simple change could be very beneficial for a lot of users.

Sorry for disturbing. @NoNameProvided Could you plz have a look at this issue?

Option strategy: 'excludeAll' behave allmost the same as excludeExtraneousValues: true, is that by design?

image It seems like that keys are the same except isMap and ignoreDecorators