class-validator

Class-validator - Quick Reference

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "class-validator" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-class-validator

Class-validator - Quick Reference

Full Reference: See advanced.md for custom validators, cross-field validation, validation groups, error formatting, and class-transformer integration.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: class-validator for comprehensive documentation.

Setup

npm install class-validator class-transformer

// tsconfig.json { "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } }

Basic Usage

import { validate, IsString, IsEmail, IsInt, Min, Max, Length, IsOptional, } from 'class-validator'; import { plainToInstance } from 'class-transformer';

class CreateUserDto { @IsString() @Length(2, 50) name: string;

@IsEmail() email: string;

@IsInt() @Min(18) @Max(120) age: number;

@IsOptional() @IsString() bio?: string; }

// Validate async function validateUser(data: unknown) { const user = plainToInstance(CreateUserDto, data); const errors = await validate(user);

if (errors.length > 0) { throw new Error(errors.map((e) => Object.values(e.constraints || {})).flat().join(', ')); }

return user; }

Common Decorators

String Validators

import { IsString, IsNotEmpty, Length, MinLength, MaxLength, Matches, IsUUID, IsEmail, IsUrl, IsIP, } from 'class-validator';

class StringValidationDto { @IsString() @IsNotEmpty() required: string;

@Length(5, 20) username: string;

@MinLength(8) @Matches(/^(?=.[A-Za-z])(?=.\d)[A-Za-z\d]{8,}$/, { message: 'Password must contain letters and numbers', }) password: string;

@IsEmail() email: string;

@IsUrl({ require_protocol: true }) website: string;

@IsUUID('4') id: string; }

Number Validators

import { IsNumber, IsInt, IsPositive, Min, Max, IsDivisibleBy } from 'class-validator';

class NumberValidationDto { @IsNumber() decimal: number;

@IsInt() integer: number;

@IsPositive() positive: number;

@Min(0) @Max(100) percentage: number; }

Date Validators

import { IsDate, MinDate, MaxDate, IsISO8601 } from 'class-validator'; import { Type } from 'class-transformer';

class DateValidationDto { @IsDate() @Type(() => Date) date: Date;

@MinDate(new Date('2020-01-01')) @Type(() => Date) afterDate: Date;

@IsISO8601() isoString: string; }

Array Validators

import { IsArray, ArrayMinSize, ArrayMaxSize, ArrayUnique, ArrayNotEmpty, ValidateNested, } from 'class-validator'; import { Type } from 'class-transformer';

class ItemDto { @IsString() name: string; }

class ArrayValidationDto { @IsArray() @ArrayNotEmpty() @ArrayMinSize(1) @ArrayMaxSize(10) @IsString({ each: true }) // Validate each item tags: string[];

@IsArray() @ValidateNested({ each: true }) @Type(() => ItemDto) items: ItemDto[]; }

Nested Object Validation

import { IsObject, ValidateNested } from 'class-validator'; import { Type } from 'class-transformer';

class AddressDto { @IsString() street: string;

@IsString() city: string; }

class UserWithAddressDto { @IsString() name: string;

@ValidateNested() @Type(() => AddressDto) address: AddressDto; }

Other Validators

import { IsBoolean, IsEnum, IsIn, IsOptional, IsCreditCard, IsPhoneNumber, } from 'class-validator';

enum UserRole { ADMIN = 'admin', USER = 'user', GUEST = 'guest', }

class MixedValidationDto { @IsBoolean() active: boolean;

@IsEnum(UserRole) role: UserRole;

@IsIn(['draft', 'published', 'archived']) status: string;

@IsOptional() @IsCreditCard() creditCard?: string; }

NestJS Integration

// main.ts import { ValidationPipe } from '@nestjs/common';

app.useGlobalPipes( new ValidationPipe({ whitelist: true, // Strip non-decorated properties forbidNonWhitelisted: true, // Throw on unknown properties transform: true, // Auto-transform payloads to DTO instances transformOptions: { enableImplicitConversion: true, }, }) );

// users.controller.ts @Controller('users') export class UsersController { @Post() create(@Body() createUserDto: CreateUserDto) { // createUserDto is already validated and transformed return this.usersService.create(createUserDto); }

@Get() findAll(@Query() query: PaginationQueryDto) { // Query params also validated return this.usersService.findAll(query); }

@Get(':id') findOne(@Param('id', ParseUUIDPipe) id: string) { return this.usersService.findOne(id); } }

Partial DTOs (for updates)

import { PartialType, OmitType, PickType, IntersectionType } from '@nestjs/mapped-types';

// All fields optional export class UpdateUserDto extends PartialType(CreateUserDto) {}

// Omit specific fields export class CreateUserWithoutPasswordDto extends OmitType(CreateUserDto, ['password']) {}

// Pick specific fields export class LoginDto extends PickType(CreateUserDto, ['email', 'password']) {}

// Combine DTOs export class ExtendedUserDto extends IntersectionType(CreateUserDto, AdditionalFieldsDto) {}

Custom Validator (Basic)

import { registerDecorator, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, } from 'class-validator';

@ValidatorConstraint({ async: false }) export class IsStrongPasswordConstraint implements ValidatorConstraintInterface { validate(password: string, args: ValidationArguments) { const hasUppercase = /[A-Z]/.test(password); const hasLowercase = /[a-z]/.test(password); const hasNumber = /\d/.test(password); const minLength = password.length >= 8;

return hasUppercase && hasLowercase && hasNumber && minLength;

}

defaultMessage(args: ValidationArguments) { return 'Password must contain uppercase, lowercase, and number'; } }

export function IsStrongPassword(validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { registerDecorator({ target: object.constructor, propertyName: propertyName, options: validationOptions, constraints: [], validator: IsStrongPasswordConstraint, }); }; }

// Usage class RegisterDto { @IsStrongPassword() password: string; }

When NOT to Use This Skill

  • Client-side validation - Use Zod with React Hook Form

  • Non-NestJS backends - Zod is more framework-agnostic

  • Functional programming patterns - Decorators require classes

  • Simple validation - Zod has simpler API

Comparison: class-validator vs Zod

Feature class-validator Zod

Style Decorators Functional

Framework NestJS standard Framework agnostic

Transform class-transformer Built-in

Bundle size Larger Smaller

Type inference Manual Automatic

Anti-Patterns

Anti-Pattern Why It's Bad Correct Approach

Missing @Type() decorator Nested validation fails Use @Type() for nested objects

No whitelist in ValidationPipe Accepts unknown properties Set whitelist: true

Using any in DTOs Bypasses validation Use proper types

Manual validation in controller Code duplication Use ValidationPipe globally

Missing experimentalDecorators Decorators don't work Enable in tsconfig.json

Not using class-transformer Plain objects not validated Use plainToInstance()

Quick Troubleshooting

Issue Cause Solution

Decorators not working tsconfig misconfigured Enable experimentalDecorators: true

Nested validation fails Missing @Type() Add @Type(() => NestedClass)

Validation not running ValidationPipe not set Add ValidationPipe globally in main.ts

Unknown properties accepted No whitelist Set whitelist: true in ValidationPipe

Transform not working Missing transform option Set transform: true in ValidationPipe

Async validators fail Wrong setup Use async: true in @ValidatorConstraint

Checklist

  • tsconfig with decorators enabled

  • class-transformer for nested/transform

  • Global ValidationPipe in NestJS

  • whitelist and forbidNonWhitelisted

  • Custom validators for specific logic

  • Error formatting for API responses

Reference

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: class-validator

  • class-validator GitHub

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

webrtc

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-19

No summary provided by upstream source.

Repository SourceNeeds Review