typestack / class-transformer

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

question: Options in @Transform Decorator Do Not Reflect Those Passed to plainToInstance in class-transformer #1676

Closed Sygun closed 2 months ago

Sygun commented 5 months ago

I was integrating the class-transformer library into my project to leverage its capabilities for transforming plain objects into class instances with complex transformations. My goal was to utilize the @Transform decorator for custom transformations and to pass specific transformation options through the plainToInstance function. Here's an example to illustrate my approach:

import { plainToInstance, Transform } from 'class-transformer';
import * as dayjs from 'dayjs';

class Appointment {
  @Transform(({ value, options }) => {
    // Expecting options to reflect the ones passed in plainToInstance, specifically 'groups' and 'excludeExtraneousValues'
    console.log(options); // However, it logs default options, not the ones passed
    return value && !options.groups.includes('no-datetime-transform')
      ? dayjs(value).format('HH:mm')
      : value;
  }, { toPlainOnly: true })
  date: string;
}

// Simulated plain object
const appointment = {
  date: '2022-04-22T10:00:00.000Z',
};

// Attempting to transform with specific options
const appointmentInstance = plainToInstance(Appointment, appointment, {
  excludeExtraneousValues: true,
  groups: ['no-datetime-transform'],
});

The problem:

While attempting to achieve the above, I encountered an issue where the options passed to plainToInstance were not being reflected inside the @Transform decorator function. Despite passing { excludeExtraneousValues: true, groups: ['no-datetime-transform'] } as options, within the @Transform decorator, the options object appears to only contain default values rather than the ones explicitly provided. This behavior deviates from my expectations, as I anticipated that the options object accessible within the @Transform decorator would mirror the options passed to plainToInstance.

This unexpected behavior is impacting my ability to perform conditional transformations based on the provided options, limiting the flexibility and utility of the class-transformer in my project. I have confirmed that my project dependencies are up to date, and I have followed the documentation and examples provided by class-transformer closely to ensure my implementation is correct.

I am seeking guidance on whether this is a known limitation, a bug, or if there is an alternative approach to achieving the desired outcome where @Transform decorator functions can access and utilize the transformation options passed to plainToInstance. Any insights, workarounds, or fixes would be greatly appreciated.

diffy0712 commented 3 months ago

Hi @Sygun,

I had a few minutes to check out this issue and found that it should be working. There are tests for this specific scenario.

What I see in your example is that you call plainToInstance, but you have the transformer with option { toPlainOnly: true } , so it will not run in this example.

Could you solve this issue or moved on with a different solution? If you still need help with this could you provide a bit more information on how to reproduce this behavior?

Edit: You need to add the @Expose decorator to the @Transform to run.

diffy0712 commented 2 months ago

I believe this question has been answered and seems inactive, so I close the issue.

github-actions[bot] commented 4 weeks ago

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.