typescript - class-validator validera nästlat objekt baserat på föräldraegenskaper


Finns det ett sätt att få ett fält i ett barnobjekt validerat baserat på egenskaper hos föräldern. Följande objekt representerar strukturen vi försöker validera. Till exempel i följande struktur är endast first.name inte obligatoriskt när id och dateOfBirth (dob) är definierade?

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

Inbäddat objekt

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

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

Giltiga inmatningar

  • id, namn.förnamn, namn.efternamn
  • id, namn.förnamn, födelsedatum
  • id, namn.efternamn, födelsedatum
  • namn.förnamn, namn.efternamn, födelsedatum

allt annat skulle anses ogiltigt

Svar #1

Här är lösningen jag kom på, vänligen låt mig veta om det skulle finnas ett bättre sätt.

Anpassad valideringsbegränsning

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

Wrapper-klass för behörighetskriterier används för att validera objekt

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

Detta används sedan i en resolverfråga på följande sätt

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

Standardvalideringsbegränsningar tillämpas på GetEligibilityArgs-klassen

Relaterade artiklar