类验证器基于父属性验证嵌套对象

时间:2020-08-12 18:38:01

标签: typescript graphql nestjs class-validator

是否有一种方法可以根据父级的属性验证子级对象中的字段。以下对象表示我们尝试验证的结构。例如,在以下结构中,在定义id和dateOfBirth(dob)时仅不需要first.name吗?

@InputType()
export class GetEligibilityArgs {       
  @Field((type) => NameInput)
  @ValidateNested()
  @Type(() => NameInput)
  name: NameInput;
 
  @Field({ nullable: true })
  @ValidateIf((o: GetEligibilityArgs) => {
    return !(o.name?.first && o.name?.last && o.dateOfBirth);
  })
  @IsNotEmpty({ message: 'id is required' })
  id?: string;

  @Field({ nullable: true })
  @ValidateIf((o: GetEligibilityArgs) => {   // <-- not sure if this is the correct way to do this
    return !(o.id && o.name?.first && o.name?.last);
  })
  @IsNotEmpty()
  dateOfBirth?: string;
}

嵌套对象

@InputType()
export class NameInput {
  @Field({ nullable: true })
  @IsNotEmpty()
  first?: string;

  @Field({ nullable: true })
  @IsNotEmpty()
  last?: string;
}

有效输入

  • id,name.first,name.last
  • id,name.first,dob
  • id,name.last,dob
  • name.first,name.last,dob

其他所有内容都将视为无效

1 个答案:

答案 0 :(得分:1)

这是我想出的解决方案,请告诉我是否有更好的方法。

自定义验证程序约束

@ValidatorConstraint()
export class GetEligibilityCriteriaConstraint implements ValidatorConstraintInterface {
  validate(
    { id, name, dateOfBirth }: GetEligibilityArgs,
    validationArguments: ValidationArguments,
  ) {
    if (id && name?.first && name?.last) {
      return true;
    }
    if (id && name?.first && dateOfBirth) {
      return true;
    }
    if (id && name?.last && dateOfBirth) {
      return true;
    }
    if (name?.first && name?.last && dateOfBirth) {
      return true;
    }
    return false;
  }

  defaultMessage(args: ValidationArguments) {
    return 'Eligibility requires 3 of the following 4 fields (id, name.first, name.last, dateOfBirth';
  }
}

资格标准包装程序类用于验证对象

@ArgsType()
export class GetEligibilityCriteria {
  @Field((type) => GetEligibilityArgs)
  @Validate(GetEligibilityCriteriaConstraint)
  @Type(() => GetEligibilityArgs)
  @ValidateNested()
  criteria: GetEligibilityArgs;
}

然后将其用于诸如此类的解析器查询中

 @Query((returns) => Eligibility)
  eligibility(@Args() { criteria }: GetEligibilityCriteria) {
    // performs some mapping and calls service 
  }

标准验证器约束应用于GetEligibilityArgs类