NestJS中能否将字段类型设为DTO数组并实现有效校验?
问题描述
我为Question和Answer实体分别创建了对应的DTO,二者为一对多关联。现需实现包含答案的问题创建功能,因此Question实体的answers字段需接收Answer项数组,故想将其类型设为CreateAnswerDto[]。
对应的CreateAnswerDto代码:
// create-answer.dto.ts export class CreateAnswerDto { @ApiProperty({ example: "This is a variant of question's answer" }) @IsEmpty() @IsString() @MaxLength(250) value: string; // ... @ApiProperty({ example: false }) @IsBoolean() @Transform(({ obj, key }) => Boolean(obj[key])) isCorrect: boolean; }
CreateQuestionDto代码:
// create-question.dto.ts export class CreateQuestionDto { @IsNotEmpty() @IsString() title: string; // ... @IsNotEmpty() @IsArray() answers: CreateAnswerDto[]; }
请问能否将其他DTO作为字段类型,且该字段能正常完成校验?
回答
完全可以将其他DTO作为字段类型并实现完整校验,但要注意NestJS的class-validator默认不会自动递归校验嵌套的DTO数组,需要添加两个关键装饰器启用嵌套校验:
@ValidateNested({ each: true }):告知class-validator需要校验数组中的每一项@Type(() => CreateAnswerDto):指定数组元素的类型,让校验器能正确识别并处理每个DTO实例
修改后的CreateQuestionDto代码如下:
// create-question.dto.ts import { IsNotEmpty, IsArray, ValidateNested } from 'class-validator'; import { Type } from 'class-transformer'; import { CreateAnswerDto } from './create-answer.dto'; export class CreateQuestionDto { @IsNotEmpty() @IsString() title: string; // ... @IsNotEmpty() @IsArray() @ValidateNested({ each: true }) @Type(() => CreateAnswerDto) answers: CreateAnswerDto[]; }
修改后,请求传入的answers数组中每个CreateAnswerDto对象都会被自动校验,确保符合定义的规则(比如value为字符串且长度不超250、isCorrect为布尔值等)。
另外注意CreateAnswerDto中的@IsEmpty()装饰器,它会要求字段值为空,这大概率和你接收用户输入的需求矛盾,建议换成@IsNotEmpty()或者直接移除,否则会导致校验失败。
内容的提问来源于stack exchange,提问作者Orozbek Zhenisbekov
相关产品推荐
相关产品推荐

