【问题标题】:Class validator: Use class member as decorator argument类验证器:使用类成员作为装饰器参数
【发布时间】:2021-05-19 07:24:58
【问题描述】:

我有一个注册 DTO,其中一个成员依赖于另一个成员。

zip 上的 IsPostalCode 需要知道 countryCode/locale,这是其他类成员之一。

是否可以使用类成员作为装饰器参数?

import {
  IsEmail,
  IsISO31661Alpha2,
  IsPostalCode,
  IsString
} from "class-validator"

export class SignupDto {
  @IsEmail()
  email: string

  @IsString()
  password: string

  @IsISO31661Alpha2()
  countryCode: string

  // Something like this
  @IsPostalCode(this.countryCode)
  zip: string
}

【问题讨论】:

    标签: node.js typescript decorator nestjs class-validator


    【解决方案1】:

    由于装饰器在打字稿中的工作方式,装饰器无法在其内部使用类属性。您可以创建一个custom validation decorator 来读取该类的其他属性并正确验证 zip 属性,但这可能需要一些工作。

    所以回答你的问题:

    是否可以使用类成员作为装饰器参数?

    不,不是。

    【讨论】:

      【解决方案2】:

      您可以创建一个自定义验证器,如下所示:

      import {
        ValidationOptions,
        registerDecorator,
        ValidationArguments,
        buildMessage,
      } from 'class-validator';
      /**
      * Install validator package from npm. class-validator uses validator under the 
      * hood
      */
      import {isISO31661Alpha2,isPostalCode} from 'validator';
      
      export function IsPostalCodeOf(
        property: string,
        validationOptions?: ValidationOptions,
      ) {
        // eslint-disable-next-line @typescript-eslint/ban-types
        return function(object: Object, propertyName: string) {
          registerDecorator({
            name: 'isPostalCodeOf',
            target: object.constructor,
            propertyName: propertyName,
            constraints: [property],
            options: validationOptions,
            validator: {
              validate(value: any, args: ValidationArguments) {
                // Getting the country code field from the argument.
                // countryCode field from SignupDto
                const [countryCodeField] = args.constraints;
                // Getting the value of the countryCode Field
                const countryCode = (args.object as any)[countryCodeField];
                // Checking if the country code is valid even though it is checked 
                // at class level 
                if (!isISO31661Alpha2(countryCode)) {
                // Invalid county code
                  return false;
                }
                // Checks if the value (zip) belongs in the extracted countryCode 
                // field
                return isPostalCode(value,countryCode);
              },
              // Specifiy your error message here.
              defaultMessage: buildMessage(
                eachPrefix =>
                  `${eachPrefix} $property must be a valid postal 
                   code in the specified country `,
                validationOptions,
              ),
            },
          });
        };
      }
      

      用法:

      export class SignupDto {
        @IsEmail()
        email: string
      
        @IsString()
        password: string
      
        @IsISO31661Alpha2()
        countryCode: string
      
        @IsPostalCodeOf('countryCode')
        zip: string
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-16
        • 2021-02-08
        • 1970-01-01
        • 2019-01-01
        • 2020-08-29
        • 1970-01-01
        • 2019-02-20
        • 2020-07-09
        相关资源
        最近更新 更多