class-transformer
class-transformer copied to clipboard
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
Expected behavior
All properties are exposed. In above example doggie = {name: 'Azor'}
Actual behavior
Properties are not exposed. In above example doggie = {}
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?
It seems like that
keys
are the same except isMap
and ignoreDecorators
@johny1614 @ImJoeHs I have the same issue. Did you find any solution?
Same here, is there any solutions for this yet?
Same here, is there any solutions for this yet?
you can use @Expose
for each property that you wanna expose it
Yes that's the only way. Clear in the code screenshot that was sent.
I feel that the property by default should respect the strategy. Don't really think it has much to do with @Expose decorator. Unless I'm missing something?
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! 👍
I would like it to work this way, too.
But afaik this is a limitation of how typescript is working.
excludeExtraneousValues works by only allowing known properties to pass.
The name
property is not known at runtime, because it has no decorator.
So without a @Expose decorator, the property is unknown and will be stripped.
However I'm wondering why class-transformer features both strategy as well as excludeExtraneousValues. As far as I understand, strategy=ExcludeAll works the same as excludeExtraneousValues=true.
I would like it to work this way, too. But afaik this is a limitation of how typescript is working. excludeExtraneousValues works by only allowing known properties to pass. The
name
property is not known at runtime, because it has no decorator. So without a @expose decorator, the property is unknown and will be stripped.However I'm wondering why class-transformer features both strategy as well as excludeExtraneousValues. As far as I understand, strategy=ExcludeAll works the same as excludeExtraneousValues=true.
exactly - This can basically be achieved but with 1 major issue - any properties that don't have any decorators on them (from this library) will not be known at run time, and as such will be removed. This will render this feature highly unreliable and confusing... Sadly, I can't see a way around that issue.
Sorry for disturbing. @NoNameProvided Could you plz have a look at this issue?
Option
strategy: 'excludeAll'
behave allmost the same asexcludeExtraneousValues: true
, is that by design?
It seems like that
keys
are the same exceptisMap
andignoreDecorators
Very off-topic, but what font is this? :)
Any news on this issue? This simple change could be very beneficial for a lot of users.
I have the same issue here, any news?
by the way i use plainToInstance, because it saids that plainToClass is deprecated
@patrick-bf Check the changelog, plainToClass has been deprecated in 0.5.0, correct.
Also, as discussed above there is no solution for this issue because of typescript limits.
IMO this issue should be closed.
Could a strategy that relies on @Type
instead of @Expose
be created? At least it would be beneficial in some cases where they are already present.
Would it be an option to take metadata from other libraries like for example class-validator
in to account to determine, wether a property is "known"?
Or maybe implement a decorator like class-validator
s @Allow()
which is basically a no-op just to make properties known to the metadata storage?
So is the only way to expose all properties is to manually @Expose each? Or is there a better way now?
I faced the same issue so I created an extension method to achieve the wanted behavior:
- 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);
}
- Use it like this:
const myInstance = transformToDto(myDTO, myData);
Any news on this issue?
@mwanago We ended up adding expose to every field.
Could this problem be solved with https://www.typescriptlang.org/tsconfig#useDefineForClassFields ?
I've done a test using the Expose decorator at class level and I was able to get the class properties with Object.getOwnPropertyNames(new object())
It has been 2 years and this has yet to be resolved.. Why?
Yeah pleassseeee fix this
I think it is a very basic requirement but a very very useful feature, for security, we don't want they call API with extra fields, and it should be filtered easily, but not decorate every field.
Thanks
Would love to see this fixed. Currently have to add a whole lot of decorators to every DTO to avoid leaking data. This would avoid that by automatically removing anything that isn't a property of the DTO.
Would also love to see this issue to be resolved!