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

如何让NestJS中class-validator的DTO字段同时支持数字与数字字符串验证?

实现方案

当然可以实现,你只需要调整字段类型并搭配合适的验证规则即可,以下是两种可行方案:

方案一:自定义验证装饰器(推荐)

先创建一个支持数字/数字字符串的自定义验证器:

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

export function IsNumberOrNumberString(validationOptions?: ValidationOptions) {
  return function (target: Object, propertyKey: string) {
    registerDecorator({
      name: 'isNumberOrNumberString',
      target: target.constructor,
      propertyName: propertyKey,
      options: validationOptions,
      validator: {
        validate(value: unknown) {
          if (typeof value === 'number') {
            return !isNaN(value) && isFinite(value);
          }
          if (typeof value === 'string') {
            return /^\d+(\.\d+)?$/.test(value) && !isNaN(Number(value));
          }
          return false;
        },
        defaultMessage() {
          return '必须是数字或合法的数字字符串';
        },
      },
    });
  };
}

然后修改你的DTO:

import { IsNotEmpty, Expose } from 'class-validator';
import { IsNumberOrNumberString } from './path-to-your-decorator';

export default class CatDto extends BaseDto {
  @IsNotEmpty()
  @Expose()
  name: string;

  @IsNotEmpty()
  @IsNumberOrNumberString()
  @Expose()
  age: number | string;
}

方案二:用@ValidateIf拆分验证规则

不需要自定义装饰器,通过条件验证分别处理两种类型:

import { IsNotEmpty, Expose, IsNumber, IsNumberString, ValidateIf } from 'class-validator';

export default class CatDto extends BaseDto {
  @IsNotEmpty()
  @Expose()
  name: string;

  @IsNotEmpty()
  // 仅当值为number类型时,校验是否为合法数字
  @ValidateIf((_, value) => typeof value === 'number')
  @IsNumber()
  // 仅当值为string类型时,校验是否为合法数字字符串
  @ValidateIf((_, value) => typeof value === 'string')
  @IsNumberString()
  @Expose()
  age: number | string;
}

可选:自动转换类型

如果希望业务逻辑中统一使用number类型,可以搭配class-transformer的@Transform装饰器,自动将数字字符串转为数字:

import { Transform } from 'class-transformer';

// 在age字段上添加
@Transform(({ value }) => {
  if (typeof value === 'string' && /^\d+(\.\d+)?$/.test(value)) {
    return Number(value);
  }
  return value;
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:22:18