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>;