如何使用class-transformer为TS字典类someClass编写校验规则?
可以实现,不过需要注意两个核心前提:
class-transformer本身仅负责普通对象到类实例的转换,校验逻辑需要配合你已经用到的class-validator共同完成- 因为你用了动态索引签名和递归联合类型,无法用内置装饰器直接校验,需要补充自定义校验逻辑
具体调整实现方案
你需要新增两个自定义校验器,分别适配递归类型someType和动态属性结构的someClass,完整可运行代码参考如下:
import { validate, ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface, ValidateNested, Validate } from 'class-validator'; import { plainToInstance } from 'class-transformer'; type someType = string | number | boolean | someType[]; // 自定义校验器:校验值符合someType类型要求 @ValidatorConstraint({ name: 'isSomeType', async: false }) class IsSomeTypeConstraint implements ValidatorConstraintInterface { validate(value: any, args: ValidationArguments) { if (['string', 'number', 'boolean'].includes(typeof value)) return true; if (Array.isArray(value)) { return value.every(item => this.validate(item, args)); } return false; } defaultMessage(args: ValidationArguments) { return 'value must be string/number/boolean or nested array of the above types'; } } // 自定义校验器:校验someClass所有动态属性符合结构要求 @ValidatorConstraint({ name: 'isValidSomeClass', async: false }) class IsValidSomeClassConstraint implements ValidatorConstraintInterface { validate(value: any, args: ValidationArguments) { if (typeof value !== 'object' || value === null || Array.isArray(value)) return false; for (const key in value) { const prop = value[key]; if (typeof prop !== 'object' || prop === null || typeof prop.value === 'undefined') return false; if (!new IsSomeTypeConstraint().validate(prop.value, args)) return false; } return true; } defaultMessage(args: ValidationArguments) { return 'each property of someClass must be an object with a valid value field'; } } class someClass { [key: string]: { value: someType; } } class someDto { @Validate(IsValidSomeClassConstraint) @ValidateNested({ each: true }) public myValue: someClass; }
实际使用时先调用class-transformer完成实例转换,再调用校验方法即可:
const plainDto = { myValue: { test1: { value: 'abc' }, test2: { value: 123 }, test3: { value: [true, 'def', 456] } } }; // 普通对象转类实例 const dtoInstance = plainToInstance(someDto, plainDto); // 执行校验 validate(dtoInstance).then(errors => { if (errors.length > 0) { console.log('校验失败:', errors); } else { console.log('校验通过'); } });
内容的提问来源于stack exchange,提问作者Dmytro Mysak
相关产品推荐
相关产品推荐

