如何基于用户输入的国家代码动态为@IsPhoneNumber()校验器传参
实现方案
class-validator的装饰器参数本身是静态常量,无法直接在运行时读取同实例其他属性动态传参,你可以通过自定义校验约束实现这个需求,完整代码如下:
1. 导入依赖
import { IsRequired, Max, Min, Validate, ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, isPhoneNumber } from 'class-validator';
2. 定义自定义校验规则
@ValidatorConstraint({ name: 'phoneWithCountry', async: false }) class IsPhoneNumberWithCountry implements ValidatorConstraintInterface { // 校验逻辑 validate(phoneValue: string, args: ValidationArguments) { // 获取当前DTO实例 const currentDto = args.object as RandomlyNamedDto; // 调用内置的手机号校验方法,传入动态获取的countryCode return isPhoneNumber(phoneValue, currentDto.countryCode); } // 自定义报错信息 defaultMessage(args: ValidationArguments) { const currentDto = args.object as RandomlyNamedDto; return `phone字段必须是符合${currentDto.countryCode}格式的有效手机号`; } }
3. 修改原有DTO
export class RandomlyNamedDto { @IsRequired() @Max(3) @Min(2) countryCode: string; // 替换原有的@IsPhoneNumber(),使用自定义校验器 @Validate(IsPhoneNumberWithCountry) phone: string; }
注意事项
- class-validator默认按属性定义顺序校验,你这里
countryCode定义在phone之前,校验phone时countryCode已经完成校验、值是可用的,不需要额外调整顺序 - 如果需要兼容
countryCode为空的场景,可以在validate方法里加判断,比如countryCode为空时默认走全球手机号校验规则即可
内容的提问来源于stack exchange,提问作者Muljayan
相关产品推荐
相关产品推荐

