I spent a lot of time with this, and I finally found a cleaner way of doing it than the current answer.
Basically, the decorator @Type
gives us some helper options if we want to use them, such us.. the object! So, you can return one type or the other conditionally, so the validation is done over one of the two types:
class Feature {
name: string
@ValidateNested()
@IsDefined()
@Type(({ object }) => {
if(object.option?.kind === 'color') return ColorFeature;
else if(object.option?.kind === 'size') return SizeFeature;
// Handle edge case where the previous ifs are not fullfiled
})
option: ColorFeature | SizeFeature
}
You can even use a switch case
or some Record for cleanliness sake in case you have more types:
@ValidateNested()
@IsDefined()
@Type(({ object }) => {
switch(object.option?.kind){
case 'color':
return ColorFeature;
case 'size':
return SizeFeature;
case 'shape':
return ShapeFeature;
default:
// Manage edge cases
}
})
option: ColorFeature | SizeFeature | ShapeFeature
Then, you also have to use validation decorators in the extended classes, so that they are correctly validated.