Discover how to stop chasing bugs in complex data and let your code validate itself!
Why Nested DTO validation in NestJS? - Purpose & Use Cases
Imagine building a form where users submit complex data with multiple layers, like an order containing customer info and a list of products.
You try to check each piece manually in your code to ensure everything is correct.
Manually checking nested data is slow and messy.
You might forget to validate some parts or write repetitive code.
Errors become hard to track and fix, making your app unreliable.
Nested DTO validation lets you define clear rules for each data layer.
The framework automatically checks all nested parts, keeping your code clean and consistent.
if (!data.customer || !data.customer.email) { throw new Error('Invalid customer'); } if (!Array.isArray(data.products)) { throw new Error('Products missing'); }
import { IsEmail, IsString, ValidateNested } from 'class-validator'; import { Type } from 'class-transformer'; class CustomerDto { @IsEmail() email: string; } class ProductDto { @IsString() name: string; } class OrderDto { @ValidateNested() @Type(() => CustomerDto) customer: CustomerDto; @ValidateNested({ each: true }) @Type(() => ProductDto) products: ProductDto[]; }
You can trust your app to catch invalid nested data automatically, making development faster and safer.
When a user submits a signup form with address details inside their profile, nested DTO validation ensures every field is correct before saving.
Manual nested data checks are error-prone and repetitive.
Nested DTO validation automates and organizes these checks.
This leads to cleaner code and more reliable apps.
Practice
@ValidateNested() in a NestJS DTO?Solution
Step 1: Understand the role of @ValidateNested()
This decorator tells NestJS to validate nested objects inside a DTO, not just the top-level properties.Step 2: Compare with other options
@Type() handles transformation, not validation. Skipping validation or setting defaults is unrelated to @ValidateNested().Final Answer:
To validate properties of nested objects inside the DTO automatically -> Option DQuick Check:
@ValidateNested() = validate nested objects [OK]
- Confusing @ValidateNested() with @Type()
- Thinking it skips validation
- Assuming it sets default values
Solution
Step 1: Identify decorators needed for nested validation
@ValidateNested() triggers validation of nested objects, but @Type() is needed to transform plain objects into class instances.Step 2: Understand why both are required
Without @Type(), validation won't work properly because the nested object won't be recognized as the correct class type.Final Answer:
Use both @ValidateNested() and @Type(() => NestedDto) -> Option AQuick Check:
Nested validation = @ValidateNested() + @Type() [OK]
- Using only one decorator and expecting full validation
- Applying @IsString() on an object property
- Forgetting to import Type from class-transformer
address.zipCode is missing when validating UserDto?
class AddressDto {
@IsString()
street: string;
@IsString()
zipCode: string;
}
class UserDto {
@IsString()
name: string;
@ValidateNested()
@Type(() => AddressDto)
address: AddressDto;
}Solution
Step 1: Check required properties in AddressDto
Both street and zipCode are decorated with @IsString(), so they are required and must be strings.Step 2: Understand nested validation in UserDto
@ValidateNested() with @Type() ensures address is validated as AddressDto, so missing zipCode causes validation to fail.Final Answer:
Validation will fail because zipCode is missing -> Option AQuick Check:
Missing required nested property = validation fails [OK]
- Assuming missing nested fields are allowed by default
- Ignoring the effect of @ValidateNested()
- Confusing missing nested fields with missing top-level fields
class ProfileDto {
@IsString()
bio: string;
}
class UserDto {
@IsString()
username: string;
@ValidateNested()
profile: ProfileDto;
}
Why will validation NOT work correctly for the nested profile property?Solution
Step 1: Identify missing decorator for nested validation
For nested validation to work, @Type(() => ProfileDto) must be added to the nested property to transform plain objects into class instances.Step 2: Understand why other options are incorrect
@IsString() is for string properties, not objects. @ValidateNested() belongs on the nested property, not the nested class. bio is a string, no nested validation needed.Final Answer:
Because @Type(() => ProfileDto) decorator is missing on profile -> Option CQuick Check:
Missing @Type() breaks nested validation [OK]
- Forgetting @Type() on nested properties
- Misplacing @ValidateNested() on nested class
- Confusing property decorators with class decorators
CompanyDto with a nested array of EmployeeDto objects. Which is the correct way to validate this nested array properly?
class EmployeeDto {
@IsString()
name: string;
@IsInt()
age: number;
}
class CompanyDto {
@IsString()
companyName: string;
@ValidateNested({ each: true })
@Type(() => EmployeeDto)
employees: EmployeeDto[];
}Solution
Step 1: Understand nested array validation
For arrays of nested objects, @ValidateNested({ each: true }) tells the validator to check each item in the array.Step 2: Confirm use of @Type() for transformation
@Type(() => EmployeeDto) converts plain objects to EmployeeDto instances, enabling validation on each employee.Final Answer:
This setup correctly validates each employee in the employees array -> Option BQuick Check:
Nested arrays need @ValidateNested({ each: true }) + @Type() [OK]
- Omitting { each: true } for arrays
- Using @IsArray() alone without nested validation
- Forgetting @Type() for nested array items
Ready to prove it?
Pass the test and this pattern moves unknown
