我想使用类验证器在 nestjs 中创建一个 DTO。
值可以接受1-24之间的值,trial or lifetime
我创建了一个这样的枚举
export enum PeriodEnum {
"trial" = "trial",
"lifetime" = "lifetime"
}
我尝试使用这个验证
@IsNotEmpty()
@ApiProperty(CustomersConfigSwagger.API_PROP_REF_PERIOD)
@Min(0)
@Max(24)
@IsEnum(Object.keys(PeriodEnum))
period: string;
如果我通过 1,我会得到一个错误:
"period must be a valid enum value",
"period must not be greater than 10",
"period must not be less than 0"
我试着补充
"1" = "1"
但是“枚举成员不能有数字”
我什至尝试使用 RegExp
@IsNotEmpty()
@ApiProperty(CustomersConfigSwagger.API_PROP_REF_PERIOD)
@Matches(`/^(${Object.keys(PeriodEnum)}|[1-9]|1[0-9]|2[0-4])$/`)
period: string;
既然你接受了
strings
,@Min
和@Max
就不再有意义了。所以在这里你需要将你的数字处理为string
.
我的建议是创建自己的
validation decorator
:
export function IsLifetimeOrTrialOrBetween1and24(
validationOptions?: ValidationOptions
) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: "IsLifetimeOrTrialOrBetween1and24",
target: object.constructor,
propertyName: propertyName,
options: validationOptions,
validator: {
validate(value: any) {
// you manage your logic here then return either TRUE or FALSE
},
},
});
};
}
然后像这样使用它:
@IsLifetimeOrTrialOrBetween1and24({
message: 'should be lifetime trial or a number between 1 and 24',
})
readonly period: string;
了解更多在这里
但是如果您不想自定义验证装饰器,这是一个丑陋的解决方案,但它工作正常:
@IsIn(['trial', 'lifetime', '1', '2', '3', '4', '5', '6', '7',...,'23','24'])
readonly period: string;
我这样编辑我的 DTO:
@IsNotEmpty()
@ApiProperty(CustomersConfigSwagger.API_PROP_REF_PERIOD)
@Matches(`^(${Object.values(PeriodEnum).join("|")}|[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4])$`)
period: string;
现在可以正常工作了
@Min()
装饰器无法检查 period
的数据类型是 string
.period
转换为有效的最小值和最大值@Type()
装饰器来投射:
@IsNotEmpty()
@ApiProperty(CustomersConfigSwagger.API_PROP_REF_PERIOD)
@Type(() => Number)
@Min(0)
@Max(24)
@IsEnum(Object.keys(PeriodEnum))
period: string;