Add Number Validation Constraints to Zod Schemas

Learn how to enhance generated Zod schemas with number validation methods like .int(), .positive(), .min(), .max(), and .finite().

Validation

Detailed Explanation

Number Validation in Zod

The basic z.number() validator accepts any finite number. Zod provides methods to constrain numbers for specific business rules.

Common Number Validators

import { z } from "zod";

const productSchema = z.object({
  // Integer only
  quantity: z.number().int("Must be a whole number"),

  // Positive number
  price: z.number().positive("Price must be positive"),

  // Range
  rating: z.number().min(1, "Min rating is 1").max(5, "Max rating is 5"),

  // Non-negative
  stock: z.number().nonnegative("Stock cannot be negative"),

  // Finite (no Infinity)
  discount: z.number().finite().min(0).max(100),

  // Multiple of
  pageSize: z.number().int().multipleOf(10),
});

Built-in Number Validators

Method Validates Example valid values
.int() Integer 1, 42, -7
.positive() > 0 1, 0.5, 100
.nonnegative() >= 0 0, 1, 100
.negative() < 0 -1, -0.5
.nonpositive() <= 0 0, -1
.min(n) >= n Depends on n
.max(n) <= n Depends on n
.finite() Not Infinity Any finite number
.multipleOf(n) Divisible by n Multiples of n
.safe() Safe integer Within Number.MAX_SAFE_INTEGER

Chaining Validators

Validators chain naturally for precise constraints:

// Percentage: integer between 0 and 100
const percentSchema = z.number().int().min(0).max(100);

// Age: positive integer under 150
const ageSchema = z.number().int().positive().max(150);

// Price: non-negative with 2 decimal places
const priceSchema = z.number().nonnegative().multipleOf(0.01);

// Port number: integer in valid range
const portSchema = z.number().int().min(1).max(65535);

Coercion from Strings

When parsing form data or query parameters, numbers arrive as strings. Use z.coerce.number():

const querySchema = z.object({
  page: z.coerce.number().int().positive().default(1),
  limit: z.coerce.number().int().min(1).max(100).default(20),
});

// Parses { page: "3", limit: "50" } into { page: 3, limit: 50 }

This eliminates manual parseInt() calls and validates in one step.

Use Case

You are building an e-commerce API and need to validate that product prices are positive numbers, quantities are non-negative integers, and discount percentages fall within 0-100.

Try It — JSON to Zod Schema

Open full tool