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

Nest.js中Class Validator实现邮箱/手机号二选一验证及自定义校验问题

在Nest.js中用class-validator实现邮箱/手机号二选一校验

一、class-validator是否支持「或」逻辑校验?

class-validator没有提供原生的@Or()这类直接实现或逻辑的装饰器,但可以通过自定义验证器结合内置校验工具函数来实现需求,这也是满足该场景最灵活的方案。

二、自定义IsEmailOrPhone验证器的正确实现方式

你遇到的核心问题是混淆了class-validator的装饰器和底层校验函数:@IsEmail()、@IsPhoneNumber()是用于给类字段添加校验规则的装饰器,而class-validator同时暴露了同名的纯函数(isEmail()、isPhoneNumber()),这些函数直接接收值并返回布尔校验结果,正好适配自定义验证器的validate方法要求。

1. 编写自定义验证器约束类

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
import { isEmail, isPhoneNumber } from 'class-validator';

@ValidatorConstraint({ name: 'isEmailOrPhone', async: false })
export class IsEmailOrPhoneConstraint implements ValidatorConstraintInterface {
  validate(value: string, args: ValidationArguments) {
    // 校验逻辑:满足邮箱格式,或满足指定区域(示例为中国)的手机号格式即可通过
    return isEmail(value) || isPhoneNumber(value, 'CN');
  }

  defaultMessage(args: ValidationArguments) {
    return '请输入有效的邮箱或手机号';
  }
}

2. 封装成可直接使用的装饰器

import { registerDecorator, ValidationOptions } from 'class-validator';
import { IsEmailOrPhoneConstraint } from './is-email-or-phone.constraint';

export function IsEmailOrPhone(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsEmailOrPhoneConstraint,
    });
  };
}

3. 在请求DTO中使用

import { IsEmailOrPhone } from './is-email-or-phone.decorator';

export class AuthRequestDto {
  @IsEmailOrPhone({ message: '请提供有效的邮箱或手机号' })
  isEmailOrPhone: string;

  // 其他请求字段...
}

三、额外扩展说明

  • 若需要支持多区域手机号校验,可修改isPhoneNumber的第二个参数为区域数组(部分版本的class-validator支持数组格式,若不支持可自行扩展逻辑判断多个区域)
  • 如果需要异步校验(比如结合数据库查询做额外判断),只需将ValidatorConstraint的async属性设为true,并让validate方法返回Promise<boolean>即可

内容的提问来源于stack exchange,提问作者Barun Bhattacharjee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:56:01