All skills
Skillintermediate
DTOs & Validation
```typescript import { IsEmail, IsString, IsOptional, IsBoolean, IsInt, MinLength, MaxLength, Min, Max, IsUUID, IsEnum, IsArray, ArrayMinSize, ValidateNested, Matches } from 'class-validator'; import { Type, Transform } from 'class-transformer'; import { ApiProperty, ApiPropertyOptional, PartialType, OmitType, PickType } from '@nestjs/swagger';
Claude Code Knowledge Pack7/10/2026
Overview
DTOs & Validation
DTO Patterns
IsEmail, IsString, IsOptional, IsBoolean, IsInt,
MinLength, MaxLength, Min, Max, IsUUID, IsEnum,
IsArray, ArrayMinSize, ValidateNested, Matches
} from 'class-validator';
@ApiProperty({ example: 'user@example.com' })
@IsEmail()
email: string;
@ApiProperty({ minLength: 8 })
@IsString()
@MinLength(8)
@Matches(/^(?=.*[A-Z])(?=.*\\d)/, { message: 'Password must contain uppercase and digit' })
password: string;
@ApiProperty()
@IsString()
@MinLength(2)
@MaxLength(50)
name: string;
@ApiPropertyOptional({ enum: UserRole, default: UserRole.USER })
@IsOptional()
@IsEnum(UserRole)
role?: UserRole = UserRole.USER;
}
// Partial for updates (all fields optional)
OmitType(CreateUserDto, ['password'] as const)
) {}
// Pick specific fields
Nested Validation
@ApiProperty({ type: [OrderItemDto] })
@IsArray()
@ArrayMinSize(1)
@ValidateNested({ each: true })
@Type(() => OrderItemDto)
items: OrderItemDto[];
@ApiProperty({ type: AddressDto })
@ValidateNested()
@Type(() => AddressDto)
shippingAddress: AddressDto;
}
@IsUUID()
productId: string;
@IsInt()
@Min(1)
@Max(100)
quantity: number;
}
Custom Validation
// Custom decorator
return function (object: object, propertyName: string) {
registerDecorator({
name: 'isStrongPassword',
target: object.constructor,
propertyName,
options,
validator: {
validate(value: string) {
return /^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[@$!%*?&]).{8,}$/.test(value);
},
defaultMessage(): string {
return 'Password must contain uppercase, lowercase, digit, and special character';
},
},
});
};
}
// Usage
@IsStrongPassword()
password: string;
Transform & Sanitize
@Transform(({ value }) => parseInt(value, 10))
@IsInt()
@Min(1)
page: number = 1;
@Transform(({ value }) => value?.trim().toLowerCase())
@IsString()
@IsOptional()
search?: string;
@Transform(({ value }) => value === 'true')
@IsBoolean()
isActive: boolean = true;
}
Enable Validation Globally
// main.ts
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // Strip unknown properties
forbidNonWhitelisted: true, // Throw on unknown properties
transform: true, // Auto-transform types
transformOptions: {
enableImplicitConversion: true,
},
}));
Quick Reference
| Decorator | Purpose |
|---|---|
@IsString() | String type |
@IsEmail() | Valid email |
@MinLength(n) | Min string length |
@IsInt(), @Min(n) | Integer validation |
@IsEnum(Enum) | Enum value |
@IsOptional() | Optional field |
@ValidateNested() | Validate nested object |
@Type(() => Class) | Transform to class |
@Transform() | Custom transform |
PartialType() | All fields optional |
OmitType() | Exclude fields |
PickType() | Include only fields |