Nest.js如何使用class-validator校验string|string[]联合类型字段
string | string[] 联合类型字段校验方案 可以通过@nestjs/class-validator实现该字段的校验,内置装饰器没有直接覆盖联合类型场景,通过自定义校验约束或者组合条件校验即可完成需求。
方案1:自定义校验约束(推荐)
自定义校验逻辑可控性最高,报错信息统一,不会出现版本兼容问题。
- 首先引入依赖并定义校验规则类:
import { IsString, IsOptional, IsPositive, Validate, ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from '@nestjs/class-validator'; @ValidatorConstraint({ name: 'isStringOrStringArray', async: false }) class IsStringOrStringArrayConstraint implements ValidatorConstraintInterface { validate(value: unknown): boolean { // 值为字符串直接通过 if (typeof value === 'string') return true; // 值为数组时,校验每一项都是字符串才通过 if (Array.isArray(value)) { return value.every(item => typeof item === 'string'); } // 其余类型全部校验失败 return false; } defaultMessage(): string { return 'message 字段必须为字符串或字符串数组'; } }
- 在DTO中使用该校验规则修饰
message字段:
export class ExternalApiErrorDto { @IsString() @IsOptional() error?: string; @Validate(IsStringOrStringArrayConstraint) message: string | string[]; @IsPositive() statusCode: number; }
NestJS项目使用时,需要将
IsStringOrStringArrayConstraint加入对应模块的providers数组中,否则框架无法加载自定义校验器。
方案2:组合条件校验(无额外类写法)
如果不想额外定义校验类,可以通过@ValidateIf按值类型匹配对应校验规则,写法如下:
import { IsString, IsOptional, IsPositive, IsArray, ValidateIf } from '@nestjs/class-validator'; export class ExternalApiErrorDto { @IsString() @IsOptional() error?: string; // 当message是字符串时,走字符串校验 @ValidateIf(obj => typeof obj.message === 'string') @IsString() // 当message是数组时,走数组+每一项字符串校验 @ValidateIf(obj => Array.isArray(obj.message)) @IsArray() @IsString({ each: true }) message: string | string[]; @IsPositive() statusCode: number; }
注意:部分低版本
@nestjs/class-validator存在多个@ValidateIf规则覆盖的问题,生产环境优先选择方案1。
内容的提问来源于stack exchange,提问作者Francisco Sanguineti Arena
相关产品推荐
相关产品推荐

