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

如何利用Class-validator将父类DTO的所有字段设为可选?

问题描述

我有一个用于创建产品的DTO:

export class CreateProductDto {
  @IsString()
  title!: string

  @IsString()
  description!: string

  @IsString()
  url!: string

  @IsNumber()
  @Min(0)
  price!: number

  @IsArray()
  @ValidateNested({ each: true })
  @ArrayMinSize(1)
  @Type(() => ImageDto)
  images!: ImageDto[]

  @IsArray()
  @ValidateNested({ each: true })
  @ArrayMinSize(1)
  @Type(() => ProductSizeDto)
  sizes!: ProductSizeDto[]
}

我需要一个用于更新产品的DTO,想通过继承这个创建DTO来避免重复代码,但需要把父类的所有字段都设为@IsOptional()。当前我的更新DTO代码如下:

export class UpdateProductDto extends CreateProductDto {
  @IsString()
  id!: string;
}

请问如何实现这个需求?


解决方案

方法一:用NestJS的PartialType(最推荐)

NestJS专门提供了PartialType工具类来处理这种场景,它能自动把父类的所有字段标记为可选,同时保留原有的所有验证规则,完全不用手动修改父类字段。

首先确保安装了@nestjs/mapped-types包:

npm install @nestjs/mapped-types
# 或者用yarn
yarn add @nestjs/mapped-types

然后修改你的UpdateProductDto:

import { PartialType } from '@nestjs/mapped-types';
import { CreateProductDto } from './create-product.dto';
import { IsString } from 'class-validator';

export class UpdateProductDto extends PartialType(CreateProductDto) {
  @IsString()
  id!: string;
}

这样一来,CreateProductDto里的所有字段都会被自动加上@IsOptional(),同时原有的@IsString()、@Min(0)等验证规则全部保留,既满足需求又避免了代码重复。

方法二:手动覆盖字段(适合特殊场景)

如果不想用PartialType,可以手动给每个父类字段重新添加装饰器,加上@IsOptional():

import { CreateProductDto } from './create-product.dto';
import { IsString, IsOptional, IsNumber, Min, IsArray, ValidateNested, ArrayMinSize, Type } from 'class-validator';
import { ImageDto } from './image.dto';
import { ProductSizeDto } from './product-size.dto';

export class UpdateProductDto extends CreateProductDto {
  @IsOptional()
  @IsString()
  title?: string;

  @IsOptional()
  @IsString()
  description?: string;

  @IsOptional()
  @IsString()
  url?: string;

  @IsOptional()
  @IsNumber()
  @Min(0)
  price?: number;

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @ArrayMinSize(1)
  @Type(() => ImageDto)
  images?: ImageDto[];

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @ArrayMinSize(1)
  @Type(() => ProductSizeDto)
  sizes?: ProductSizeDto[];

  @IsString()
  id!: string;
}

这种方法虽然能实现需求,但会导致大量重复代码,失去了继承的意义,只适合需要对个别字段做特殊调整的情况。


内容的提问来源于stack exchange,提问作者Kuari Developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:11:30