【问题标题】:class-validator validate union type类验证器验证联合类型
【发布时间】:2020-05-20 07:58:54
【问题描述】:
我有一个mongoose discriminator schema,这意味着数据会根据其中一个属性而有所不同。
class Feature {
name: string
option: ColorFeature|SizeFeature
}
class ColorFeature {
kind: 'color'
color: string
}
class SizeFeature {
kind: 'size'
size: number
}
验证Feature 类以使其仅接受两种不同类型的正确方法是什么?
【问题讨论】:
标签:
typescript
class-validator
【解决方案1】:
可以通过validateNested()和class-transformer discriminator一起使用来实现
class BaseFeature {
kind: 'size' | 'color'
}
class ColorFeature extends BaseFeature {
kind: 'size'
color: string
}
class SizeFeature extends BaseFeature {
kind: 'size'
size: number
}
class Feature {
name: string
@ValidateNested()
@Type(() => BaseFeature, {
keepDiscriminatorProperty: true,
discriminator: {
property: 'kind',
subTypes: [
{ value: SizeFeature, name: 'size' },
{ value: ColorFeature, name: 'color' },
],
},
})
option: SizeFeature | ColorFeature;
}
【解决方案2】:
我为此花了很多时间,终于找到了比当前答案更简洁的方法。
基本上,装饰器@Type 为我们提供了一些帮助选项,如果我们想使用它们,比如我们.. 对象!因此,您可以有条件地返回一种或另一种类型,因此验证是通过两种类型之一完成的:
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
}
如果您有更多类型,您甚至可以使用switch case 来保持清洁:
@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
然后,您还必须在扩展类中使用验证装饰器,以便正确验证它们。