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

如何将DTO属性设为可选,但禁止全部属性为空?

实现class-validator类级验证:至少一个属性非空

你要的这种「所有属性可选,但不能全为空」的逻辑,class-validator没有现成的装饰器,但可以通过自定义类级验证器来实现,比用groups更贴合需求。

步骤1:自定义类级验证器

先写一个验证规则,用来检查DTO实例是否至少有一个属性非空:

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, registerDecorator, ValidationOptions } from 'class-validator';

@ValidatorConstraint({ name: 'atLeastOneNotEmpty', async: false })
export class AtLeastOneNotEmptyConstraint implements ValidatorConstraintInterface {
  validate(object: Record<string, any>, args: ValidationArguments) {
    // 遍历对象属性,判断是否存在非null/undefined的值
    return Object.values(object).some(value => value !== null && value !== undefined);
  }

  defaultMessage(args: ValidationArguments) {
    return '更新操作至少需要提供一个属性(name/email/password)';
  }
}

// 封装成类装饰器,方便直接用在DTO上
export function AtLeastOneNotEmpty(validationOptions?: ValidationOptions) {
  return function (object: any) {
    registerDecorator({
      target: object.constructor,
      options: validationOptions,
      constraints: [],
      validator: AtLeastOneNotEmptyConstraint,
    });
  };
}

步骤2:在DTO上使用自定义装饰器

把刚才的装饰器加到你的UpdateUsersDTO类上即可:

import { IsString, IsOptional, IsEmail, IsStrongPassword } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { AtLeastOneNotEmpty } from './path-to-your-validator'; // 替换成验证器实际路径
import { EmailIsUniq } from './your-custom-validators'; // 你的邮箱唯一验证器

@AtLeastOneNotEmpty() // 核心:添加类级验证规则
export class UpdateUsersDTO {
  @IsString()
  @IsOptional()
  @ApiProperty()
  name: string;

  @IsEmail()
  @EmailIsUniq({ message: 'This email is already being used' })
  @IsOptional()
  @ApiProperty()
  email: string;

  @IsString()
  @IsStrongPassword({
    minLength: 8,
    minLowercase: 1,
    minNumbers: 1,
    minSymbols: 1,
    minUppercase: 1,
  })
  @IsOptional()
  @ApiProperty()
  password: string;
}

补充说明

你之前尝试的groups验证器不适用这个场景——groups的作用是给验证规则分组,比如「新增用户」用一组规则、「更新用户」用另一组,但它无法实现「至少一个属性非空」这种类级别的逻辑判断。

内容的提问来源于stack exchange,提问作者Wilson de Freitas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 01:29:59