00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Stringhe e Numeri

Validazioni per Stringhe

Zod offre un ricco set di metodi per validare le stringhe. Ogni metodo restituisce un nuovo schema, permettendo il chaining.

Lunghezza

import { z } from "zod";

z.string().min(3, "Minimo 3 caratteri");
z.string().max(100, "Massimo 100 caratteri");
z.string().length(5, "Deve essere esattamente 5 caratteri");

Email, URL e UUID

const emailSchema = z.string().email("Email non valida");
emailSchema.parse("utente@esempio.it"); // OK
emailSchema.parse("non-valida");         // Errore

const urlSchema = z.string().url("URL non valido");
urlSchema.parse("https://esempio.it"); // OK

const uuidSchema = z.string().uuid("UUID non valido");
uuidSchema.parse("550e8400-e29b-41d4-a716-446655440000"); // OK

Regex

const codFiscale = z.string().regex(
  /^[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$/,
  "Codice fiscale non valido"
);

codFiscale.parse("RSSMRA85M01H501Z"); // OK

Trim, toLowerCase, toUpperCase

Questi metodi trasformano la stringa oltre a validarla:

const nome = z.string().trim().toLowerCase();
nome.parse("  MARCO  "); // => "marco"

const codice = z.string().trim().toUpperCase();
codice.parse(" abc123 "); // => "ABC123"

startsWith e endsWith

const percorso = z.string().startsWith("/api", "Deve iniziare con /api");
percorso.parse("/api/utenti"); // OK
percorso.parse("/home");       // Errore

const file = z.string().endsWith(".ts", "Deve essere un file TypeScript");
file.parse("schema.ts"); // OK
file.parse("schema.js"); // Errore

Datetime e IP

// ISO 8601 datetime
const dataSchema = z.string().datetime();
dataSchema.parse("2026-02-10T14:30:00Z"); // OK

// Con offset timezone
const dataOffset = z.string().datetime({ offset: true });
dataOffset.parse("2026-02-10T14:30:00+01:00"); // OK

// Indirizzo IP
const ipv4 = z.string().ip({ version: "v4" });
ipv4.parse("192.168.1.1"); // OK

const ipv6 = z.string().ip({ version: "v6" });
ipv6.parse("::1"); // OK

// Qualsiasi versione
const ip = z.string().ip();
ip.parse("192.168.1.1"); // OK
ip.parse("::1");         // OK

Includes e CUID

// Verifica che la stringa contenga una sottostringa
const descrizione = z.string().includes("importante", {
  message: "Deve contenere la parola 'importante'"
});

// CUID / CUID2
const cuid = z.string().cuid();
const cuid2 = z.string().cuid2();

Validazioni per Numeri

Int, Positive e Negative

z.number().int("Deve essere un intero");
z.number().positive("Deve essere positivo");       // > 0
z.number().nonnegative("Deve essere >= 0");        // >= 0
z.number().negative("Deve essere negativo");       // < 0
z.number().nonpositive("Deve essere <= 0");        // <= 0

Min, Max e Range

const eta = z.number()
  .int()
  .min(0, "L'età non può essere negativa")
  .max(150, "Età non valida");

eta.parse(25);  // OK
eta.parse(-1);  // Errore
eta.parse(200); // Errore

Puoi anche usare gt, gte, lt, lte:

z.number().gt(5);   // > 5
z.number().gte(5);  // >= 5
z.number().lt(10);  // < 10
z.number().lte(10); // <= 10

Finite e MultipleOf

// Rifiuta Infinity e -Infinity
const finito = z.number().finite();
finito.parse(42);       // OK
finito.parse(Infinity); // Errore

// Multiplo di un numero (utile per prezzi, step)
const prezzo = z.number().multipleOf(0.01);
prezzo.parse(19.99); // OK
prezzo.parse(19.999); // Errore

const pari = z.number().multipleOf(2);
pari.parse(4); // OK
pari.parse(3); // Errore

Safe Integer

// Solo numeri nell'intervallo Number.MIN_SAFE_INTEGER - Number.MAX_SAFE_INTEGER
const safeNum = z.number().safe();
safeNum.parse(42);                            // OK
safeNum.parse(Number.MAX_SAFE_INTEGER + 1);   // Errore

Esempio Completo

const FormRegistrazione = z.object({
  username: z.string()
    .min(3, "Minimo 3 caratteri")
    .max(20, "Massimo 20 caratteri")
    .regex(/^[a-zA-Z0-9_]+$/, "Solo lettere, numeri e underscore"),
  email: z.string()
    .email("Email non valida")
    .toLowerCase(),
  password: z.string()
    .min(8, "Minimo 8 caratteri")
    .regex(/[A-Z]/, "Deve contenere almeno una maiuscola")
    .regex(/[0-9]/, "Deve contenere almeno un numero"),
  eta: z.number()
    .int("L'età deve essere un numero intero")
    .min(13, "Devi avere almeno 13 anni")
    .max(120, "Età non valida"),
  peso: z.number()
    .positive("Il peso deve essere positivo")
    .multipleOf(0.1)
    .optional(),
});

type FormRegistrazione = z.infer<typeof FormRegistrazione>;