代码之家  ›  专栏  ›  技术社区  ›  Muljayan

根据用户输入动态地将国家代码传递给@IsPhoneNumber()

  •  0
  • Muljayan  · 技术社区  · 4 年前

    我有一个DTO,它使用类验证器,如下所示。

    export class RandomlyNamedDto {
      @IsRequired()
      @Max(3)
      @Min(2)
      countryCode: string;
      
      @IsPhoneNumber()
      phone: string;
    }
    

    我想把国家代码传给 @IsPhoneNumber() 基于用户发送的国家代码。例如,如果countryCode='UK',验证器将如下所示。

    IsPhoneNumber('UK')

    0 回复  |  直到 4 年前
        1
  •  2
  •   jack    4 年前

    您可以通过创建一个自定义装饰器并将其注册到类验证器库来实现这一点。 下面的代码是 adapted from another stack overflow answer 以符合您的标准:

    import {
      ValidationOptions,
      registerDecorator,
      ValidationArguments,
      buildMessage,
      IsDefined,
      validate,
      isPhoneNumber,
      MaxLength,
      MinLength,
    } from "class-validator";
    
    export function IsPhoneNumberForRegion(
      property: string,
      validationOptions?: ValidationOptions
    ) {
      return function (object: Object, propertyName: string) {
          registerDecorator({
            name: "isPhoneNumberForRegion",
            target: object.constructor,
            propertyName: propertyName,
            constraints: [property],
            options: validationOptions,
            validator: {
                validate(value: any, args: ValidationArguments) {
                  // the property name that holds the country code
                  const [countryCodeField] = args.constraints;
    
                  // the value of the country code on the target object
                  const countryCode = (args.object as any)[countryCodeField];
    
                  // validate phone number for specified region
                  return isPhoneNumber(value, countryCode);
                },
                // specify custom error message
                defaultMessage: buildMessage(
                (eachPrefix) =>
                  `${eachPrefix} $property must be a valid phone number in the specified region`,
                validationOptions
                ),
            },
        });
      };
    }
    
    class ExampleUsage {
      @IsDefined()
      @MaxLength(3)
      @MinLength(2)
      countryCode: string;
    
      @IsPhoneNumberForRegion("countryCode")
      phone: string;
    
      constructor(countryCode: string, phone: string) {
        this.phone = phone;
        this.countryCode = countryCode;
      }
    }
    
    (async () => {
      const exampleGood = new ExampleUsage("US", "(201)-867-5309");
      const validationPasses = await validate(exampleGood);
      console.log(validationPasses);
    
      const exampleErrors = new ExampleUsage("US", "not a phone number");
      const validationWithErrors = await validate(exampleErrors);
      console.log(validationWithErrors);
    })();
    
    推荐文章