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
