Multiple @Type class converters of the same class for subtypes of different types
P粉702946921
2023-08-03 13:32:17
<p>Follow me, it might get a little confusing:</p><p><ul><li>I'm using NestJs and class-validator/transformer. </li><li>There is an array that can contain two types. </li><li>I use @Type to define items via discriminators. </li><li>I am using Transform because it is required in serialization, otherwise empty object will be created. </li></ul></p><p>Now the problem is that my discriminator is an enum with 7 values, 6 of them point to one class and the last one points to another kind. The problem is that no matter what the enum type is, when serializing it is always changed to the first subtype. </p><p><br /></p>
<pre class="brush:js;toolbar:false;">enum DiscrType = {A: "a", B: "b", C: "c"}
class Discriminator {
@IsEnum(DiscrType)
type: DiscrType
}
class ClassONE extends Discriminator {...}
class ClassTWO extends Discriminator {...}
class Stuff {
@Type(() => Discriminator, {
discriminator: {
property: 'type',
subTypes: [
{ value: ClassTWO, name: DiscrType.C},
{ value: ClassONE, name: DiscrType.A}, // Always turns into this value even if it was B
{ value: ClassONE, name: DiscrType.B},
],
},
keepDiscriminatorProperty: true,
})
@Transform(
({ value }) =>
value?.map((object: ClassONE | ClassTWO ) =>
object.type === DiscrType.C
? plainToClass(classTWO, object)
: plainToClass(ClassONE, object),
),
)
@ValidateNested({each: true})
property: (ClassONE | ClassTWO )[]
}
</pre>
<p>Behavior:</p>
<pre class="brush:js;toolbar:false;">new Stuff({type: DiscrType.B,...}) // Serialization with Class Serializer
// Expected:
x = {type: "b",...}
// Actual:
x = {type: "a",...}<span style="font-family:'sans serif, tahoma, verdana, helvetica';"><span style="white-space:nowrap;" > </span></span></pre>
<p><br /></p>
So far, I'm not sure if this is the perfect solution, but in my project, after replacing @Type with this, all the tests still run.
Since this method works, I will leave it as the solution, but please mention if you know why you should use discriminator instead of this solution, what are the benefits?