class-validator 根据父属性验证嵌套对象

class-validator validate nested object based on parent properties

有没有办法根据父对象的属性验证子对象中的字段。以下对象代表我们试图验证的结构。例如在下面的结构中只有 first.name 在定义了 id 和 dateOfBirth (dob) 时不需要?

@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;
}

有效输入

所有其他都将被视为无效

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

自定义验证器约束

@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';
  }
}

资格标准包装器Class 用于验证对象

@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 class