or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-object-validation.mdcommon-decorators.mdcore-validation.mdcustom-validation-schema.mdindex.mdnumber-date-validation.mdstring-validation.mdtype-validation.md
tile.json

number-date-validation.mddocs/

Number and Date Validation

Number and date validation decorators provide constraints for numeric values and date ranges. These validators ensure that numbers fall within acceptable ranges and dates meet temporal requirements, making them essential for business logic validation, data integrity, and input sanitization.

Capabilities

Number Range Validation

Validate numeric values against minimum and maximum constraints.

/**
 * Check that number is greater than or equal to minimum value
 * @param min - Minimum value (inclusive)
 * @param validationOptions - Validation configuration options
 */
@Min(min: number, validationOptions?: ValidationOptions): PropertyDecorator;

/**
 * Check that number is less than or equal to maximum value
 * @param max - Maximum value (inclusive)
 * @param validationOptions - Validation configuration options
 */
@Max(max: number, validationOptions?: ValidationOptions): PropertyDecorator;

Number Sign Validation

Validate whether numbers are positive or negative.

/**
 * Check that number is positive (greater than zero)
 * @param validationOptions - Validation configuration options
 */
@IsPositive(validationOptions?: ValidationOptions): PropertyDecorator;

/**
 * Check that number is negative (less than zero)
 * @param validationOptions - Validation configuration options
 */
@IsNegative(validationOptions?: ValidationOptions): PropertyDecorator;

Number Divisibility Validation

Validate numeric divisibility relationships.

/**
 * Check that number is divisible by specified divisor
 * @param num - Divisor number
 * @param validationOptions - Validation configuration options
 */
@IsDivisibleBy(num: number, validationOptions?: ValidationOptions): PropertyDecorator;

Date Range Validation

Validate dates against minimum and maximum temporal constraints.

/**
 * Check that date is after or equal to minimum date
 * @param date - Minimum date (inclusive) or function returning minimum date
 * @param validationOptions - Validation configuration options
 */
@MinDate(date: Date | (() => Date), validationOptions?: ValidationOptions): PropertyDecorator;

/**
 * Check that date is before or equal to maximum date
 * @param date - Maximum date (inclusive) or function returning maximum date
 * @param validationOptions - Validation configuration options
 */
@MaxDate(date: Date | (() => Date), validationOptions?: ValidationOptions): PropertyDecorator;

Usage Examples

Basic Number Range Validation

import { Min, Max, IsNumber } from "class-validator";

class ProductPricing {
  @IsNumber()
  @Min(0)
  price: number; // Must be non-negative
  
  @IsNumber()
  @Min(0)
  @Max(100)
  discountPercent: number; // Between 0 and 100
  
  @IsNumber()
  @Min(1)
  quantity: number; // At least 1
}

const pricing = new ProductPricing();
pricing.price = 29.99; // Valid
pricing.discountPercent = 15; // Valid
pricing.quantity = 5; // Valid

// These would fail validation:
// pricing.price = -10; // Below minimum
// pricing.discountPercent = 150; // Above maximum
// pricing.quantity = 0; // Below minimum

Age and Score Validation

import { Min, Max, IsInt } from "class-validator";

class UserProfile {
  @IsInt()
  @Min(13)
  @Max(120)
  age: number; // Age between 13 and 120
  
  @IsInt()
  @Min(0)
  @Max(1000)
  gameScore: number; // Score between 0 and 1000
  
  @IsNumber()
  @Min(0.0)
  @Max(5.0)
  rating: number; // Rating between 0.0 and 5.0
}

const user = new UserProfile();
user.age = 25; // Valid
user.gameScore = 750; // Valid
user.rating = 4.5; // Valid

Positive and Negative Number Validation

import { IsPositive, IsNegative, IsNumber } from "class-validator";

class FinancialTransaction {
  @IsNumber()
  @IsPositive()
  income: number; // Must be positive
  
  @IsNumber()
  @IsNegative()
  expense: number; // Must be negative
  
  @IsNumber()
  balance: number; // Can be positive, negative, or zero
}

const transaction = new FinancialTransaction();
transaction.income = 1500.00; // Valid (positive)
transaction.expense = -250.00; // Valid (negative)
transaction.balance = 1250.00; // Valid (can be any number)

// These would fail validation:
// transaction.income = -100; // Must be positive
// transaction.expense = 200; // Must be negative

Divisibility Validation

import { IsDivisibleBy, IsInt } from "class-validator";

class GridConfiguration {
  @IsInt()
  @IsDivisibleBy(2)
  width: number; // Must be even number
  
  @IsInt()
  @IsDivisibleBy(3)
  columns: number; // Must be divisible by 3
  
  @IsInt()
  @IsDivisibleBy(5)
  batchSize: number; // Must be multiple of 5
}

const grid = new GridConfiguration();
grid.width = 100; // Valid (divisible by 2)
grid.columns = 12; // Valid (divisible by 3)
grid.batchSize = 25; // Valid (divisible by 5)

// These would fail validation:
// grid.width = 101; // Not divisible by 2
// grid.columns = 10; // Not divisible by 3
// grid.batchSize = 23; // Not divisible by 5

Date Range Validation

import { MinDate, MaxDate, IsDate } from "class-validator";

class EventSchedule {
  @IsDate()
  @MinDate(new Date())
  startDate: Date; // Must be today or later
  
  @IsDate()
  @MinDate(new Date())
  @MaxDate(new Date(Date.now() + 365 * 24 * 60 * 60 * 1000))
  endDate: Date; // Between now and one year from now
  
  @IsDate()
  @MinDate(new Date('1900-01-01'))
  @MaxDate(new Date())
  birthDate: Date; // Between 1900 and today
}

const event = new EventSchedule();
event.startDate = new Date(Date.now() + 86400000); // Tomorrow (valid)
event.endDate = new Date(Date.now() + 30 * 86400000); // 30 days from now (valid)
event.birthDate = new Date('1990-05-15'); // Valid historical date

Dynamic Date Constraints

import { MinDate, MaxDate, IsDate } from "class-validator";

class BookingSystem {
  @IsDate()
  @MinDate(() => new Date()) // Dynamic minimum date (always current time)
  checkInDate: Date;
  
  @IsDate()
  @MinDate(() => {
    const tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1);
    return tomorrow;
  })
  checkOutDate: Date; // Must be at least tomorrow
  
  @IsDate()
  @MaxDate(() => {
    const maxBooking = new Date();
    maxBooking.setFullYear(maxBooking.getFullYear() + 2);
    return maxBooking;
  })
  reservationDate: Date; // Cannot be more than 2 years in advance
}

Combined Number Validations

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

class BatchProcessingConfig {
  @IsInt()
  @IsPositive()
  @Min(10)
  @Max(1000)
  @IsDivisibleBy(10)
  batchSize: number; // Positive integer, 10-1000, divisible by 10
  
  @IsNumber()
  @Min(0.1)
  @Max(10.0)
  timeoutSeconds: number; // Between 0.1 and 10 seconds
  
  @IsInt()
  @Min(1)
  @Max(10)
  maxRetries: number; // 1 to 10 retries
}

const config = new BatchProcessingConfig();
config.batchSize = 100; // Valid (positive, in range, divisible by 10)
config.timeoutSeconds = 2.5; // Valid (in range)
config.maxRetries = 3; // Valid (in range)

Age and Experience Validation

import { Min, Max, IsInt, ValidateIf } from "class-validator";

class EmployeeProfile {
  @IsInt()
  @Min(18)
  @Max(70)
  age: number;
  
  @IsInt()
  @Min(0)
  @Max(50)
  yearsExperience: number;
  
  @ValidateIf(o => o.age < 25)
  @Max(5) // If under 25, max 5 years experience
  @IsInt()
  juniorExperience?: number;
}

const employee = new EmployeeProfile();
employee.age = 28;
employee.yearsExperience = 5;
// juniorExperience not needed since age >= 25

Financial Calculations

import { Min, Max, IsPositive, IsNumber } from "class-validator";

class LoanCalculation {
  @IsNumber()
  @IsPositive()
  @Min(1000)
  @Max(1000000)
  principal: number; // Loan amount between $1,000 and $1,000,000
  
  @IsNumber()
  @IsPositive()
  @Min(0.01)
  @Max(30.0)
  interestRate: number; // Interest rate between 0.01% and 30%
  
  @IsInt()
  @Min(1)
  @Max(30)
  termYears: number; // Loan term between 1 and 30 years
}

const loan = new LoanCalculation();
loan.principal = 250000; // Valid
loan.interestRate = 4.5; // Valid
loan.termYears = 15; // Valid

Date Validation for Business Rules

import { MinDate, MaxDate, IsDate, ValidateIf } from "class-validator";

class ProjectTimeline {
  @IsDate()
  @MinDate(new Date())
  projectStart: Date; // Cannot start in the past
  
  @IsDate()
  @MinDate(() => {
    // Project must run at least 1 week
    const minEnd = new Date();
    minEnd.setDate(minEnd.getDate() + 7);
    return minEnd;
  })
  projectEnd: Date;
  
  @IsDate()
  @ValidateIf(o => o.milestoneRequired === true)
  @MinDate(() => new Date()) // Only validate if milestone is required
  milestoneDate?: Date;
  
  milestoneRequired: boolean;
}

const project = new ProjectTimeline();
project.projectStart = new Date(Date.now() + 86400000); // Tomorrow
project.projectEnd = new Date(Date.now() + 30 * 86400000); // 30 days from now
project.milestoneRequired = true;
project.milestoneDate = new Date(Date.now() + 14 * 86400000); // 2 weeks from now

Common Validation Patterns

Range Validation with Dependencies

import { Min, Max, ValidateIf } from "class-validator";

class PricingTier {
  @IsNumber()
  @Min(0)
  @Max(100)
  discountPercent: number;
  
  @ValidateIf(o => o.discountPercent > 50)
  @Min(100) // If discount > 50%, minimum order must be 100
  minimumOrder?: number;
}

Seasonal Date Constraints

import { MinDate, MaxDate, IsDate } from "class-validator";

class SeasonalBooking {
  @IsDate()
  @MinDate(() => {
    const seasonStart = new Date();
    seasonStart.setMonth(5, 1); // June 1st
    return seasonStart;
  })
  @MaxDate(() => {
    const seasonEnd = new Date();
    seasonEnd.setMonth(8, 30); // September 30th
    return seasonEnd;
  })
  bookingDate: Date; // Summer season only
}

Age-Based Validation

import { Min, Max, ValidateIf } from "class-validator";

class AgeRestrictedService {
  @IsInt()
  @Min(0)
  @Max(120)
  age: number;
  
  @ValidateIf(o => o.age >= 18)
  @Min(1)
  @Max(10)
  adultServiceLevel?: number; // Only for adults
  
  @ValidateIf(o => o.age < 18)
  @Min(1)
  @Max(3)
  minorServiceLevel?: number; // Only for minors
}