You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:32:40