Capítulo 8 de 61

Chapter 8: Numbers

Core Idea

z.number() validates any finite JS number (rejecting NaN and Infinity), with a set of chainable range/step checks covering the common numeric constraints.

Key Concepts

  • z.number(): accepts finite numbers only — NaN and Infinity both fail validation.
  • .gt() / .gte() (alias .min()) / .lt() / .lte() (alias .max()): range comparisons.
  • .positive() (alias .gt(0)) / .nonnegative() / .negative() / .nonpositive(): sign checks.
  • .multipleOf() (alias .step()): constrains the value to a multiple of a given number.
  • z.nan(): the dedicated schema for validating that a value is NaN (the opposite of z.number()'s default behavior).

Code Examples

const schema = z.number();
schema.parse(3.14);      // ok
schema.parse(NaN);       // throws
schema.parse(Infinity);  // throws

z.number().gt(5);
z.number().gte(5);        // alias .min(5)
z.number().positive();    // alias .gt(0)
z.number().multipleOf(5); // alias .step(5)

z.nan().parse(NaN); // ok
  • What it demonstrates: z.number() excludes non-finite values by default; z.nan() exists specifically for the rare case of wanting to accept NaN.

Key Takeaways

  1. z.number() already excludes NaN/Infinity — no need for a manual .refine(Number.isFinite).
  2. Range and sign checks (.positive(), .gte()) are aliases over the same underlying .gt/.gte/.lt/.lte primitives — pick whichever reads more clearly at the call site.
  3. .multipleOf() is the right tool for step constraints (e.g. prices in cents, quantities in packs of N).

Connects To

  • Integers: z.int()/z.int32() for whole-number-only validation.
  • BigInts: the bigint equivalent of this chapter's range/sign checks.