All quizzesMedium
Custom Pipeline Elements — Series 3
Preview — 3 of 10 questions
Why are both decorators needed?
javascript
export class AddressDto {
@IsString() city: string;
}
export class CreateUserDto {
@IsString() name: string;
@ValidateNested()
@Type(() => AddressDto)
address: AddressDto;
}A@ValidateNested() alone is enough; @Type() is only for the OpenAPI document
B@Type() alone is enough, since it implies nested validation
C@ValidateNested() tells the validator to descend into the property, and @Type() tells the transformer which class to instantiate it as — without the latter, the nested value stays a plain object carrying no constraint metadata, so the descent finds nothing to check
D@Type() converts the nested object to a string before validation
What does @ValidateIf accomplish?
javascript
export class PayoutDto {
@IsIn(['bank', 'paypal']) method: 'bank' | 'paypal';
@ValidateIf((o: PayoutDto) => o.method === 'bank')
@IsString() iban: string;
@ValidateIf((o: PayoutDto) => o.method === 'paypal')
@IsEmail() paypalEmail: string;
}AThe constraints below it are evaluated only when the predicate holds, so one DTO can express a discriminated payload without demanding fields that are irrelevant to the chosen branch
BIt marks the property optional, exactly like @IsOptional()
CIt runs the predicate after validation and rejects the request if it returns false
DIt applies only to nested objects
What does the useContainer call do?
javascript
@ValidatorConstraint({ async: true })
@Injectable()
export class IsEmailAvailable implements ValidatorConstraintInterface {
constructor(private readonly users: UsersService) {}
validate(email: string) { return this.users.isEmailAvailable(email); }
}
// main.ts
useContainer(app.select(AppModule), { fallbackOnErrors: true });AIt replaces Nest's injector with class-validator's own container
BIt registers every DTO as a provider so validation can resolve them
CIt caches validation results between requests
DIt tells class-validator to resolve constraint classes through Nest's container instead of instantiating them itself — which is what allows UsersService to be injected; fallbackOnErrors keeps built-in constraints working when a class is not registered as a provider
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.