Validation Zod 4 - Patterns et changements

VérifiéSûr

Présente les modèles de validation de schéma Zod 4, y compris les changements cassants par rapport à la version 3 comme les validateurs de premier niveau (z.email(), z.uuid()) et le paramètre error à la place de message. Utile pour migrer de Zod 3 vers 4 ou pour écrire des schémas avec la nouvelle syntaxe de Zod 4.

Spar Skills Guide Bot
DeveloppementIntermédiaire
16002/06/2026
Claude Code
#zod#schema-validation#typescript

Recommandé pour

Notre avis

Ce skill fournit des patrons de validation de schémas avec Zod 4, incluant les changements cassants par rapport à Zod 3.

Points forts

  • Couvre les principaux changements cassants entre Zod 3 et Zod 4
  • Offre des exemples concrets pour les schémas de base, objets, unions, transformations
  • Inclut la gestion d'erreurs et les validations personnalisées avec refine et superRefine

Limites

  • Ne couvre pas exhaustivement toutes les fonctionnalités de Zod 4
  • Suppose une connaissance préalable de TypeScript et de la validation de schémas
  • Les exemples sont en anglais, ce qui peut être une barrière pour certains utilisateurs francophones
Quand l'utiliser

Utilisez ce skill pour migrer de Zod 3 à Zod 4 ou pour apprendre les bases de la validation de schémas avec Zod 4 dans un projet TypeScript.

Quand l'éviter

Ne l'utilisez pas si vous utilisez encore Zod 3 ou si vous travaillez avec une autre bibliothèque de validation comme Yup ou Joi.

Analyse de sécurité

Sûr
Score qualité88/100

The skill is a documentation guide for Zod 4 schema validation with code examples. There are no executable commands, network requests, or destructive actions. It is purely informational and safe.

Aucun point d'attention détecté

Exemples

Email and password schema
Create a Zod 4 schema for an object with an email field (validated as email) and a password field (min 8 chars, must contain uppercase letter and number). Include custom error messages.
Breaking changes migration
What are the main breaking changes between Zod 3 and Zod 4 for string validations like email, uuid, url, and nonempty? Show me the old and new syntax.
Discriminated union for API response
Define a Zod 4 discriminated union for an API response that can be either success (with data) or error (with error message).

name: zod-4 description: > Zod 4 schema validation patterns. Trigger: When using Zod for validation - breaking changes from v3. license: Apache-2.0 metadata: version: '1.0'

Breaking Changes from Zod 3

// ❌ Zod 3 (OLD)
z.string().email();
z.string().uuid();
z.string().url();
z.string().nonempty();
z.object({ name: z.string() }).required_error('Required');

// ✅ Zod 4 (NEW)
z.email();
z.uuid();
z.url();
z.string().min(1);
z.object({ name: z.string() }, { error: 'Required' });

Basic Schemas

import { z } from 'zod';

// Primitives
const stringSchema = z.string();
const numberSchema = z.number();
const booleanSchema = z.boolean();
const dateSchema = z.date();

// Top-level validators (Zod 4)
const emailSchema = z.email();
const uuidSchema = z.uuid();
const urlSchema = z.url();

// With constraints
const nameSchema = z.string().min(1).max(100);
const ageSchema = z.number().int().positive().max(150);
const priceSchema = z.number().min(0).multipleOf(0.01);

Object Schemas

const userSchema = z.object({
  id: z.uuid(),
  email: z.email({ error: 'Invalid email address' }),
  name: z.string().min(1, { error: 'Name is required' }),
  age: z.number().int().positive().optional(),
  role: z.enum(['admin', 'user', 'guest']),
  metadata: z.record(z.string(), z.unknown()).optional()
});

type User = z.infer<typeof userSchema>;

// Parsing
const user = userSchema.parse(data); // Throws on error
const result = userSchema.safeParse(data); // Returns { success, data/error }

if (result.success) {
  console.log(result.data);
} else {
  console.log(result.error.issues);
}

Arrays and Records

// Arrays
const tagsSchema = z.array(z.string()).min(1).max(10);
const numbersSchema = z.array(z.number()).nonempty();

// Records (objects with dynamic keys)
const scoresSchema = z.record(z.string(), z.number());
// { [key: string]: number }

// Tuples
const coordinatesSchema = z.tuple([z.number(), z.number()]);
// [number, number]

Unions and Discriminated Unions

// Simple union
const stringOrNumber = z.union([z.string(), z.number()]);

// Discriminated union (more efficient)
const resultSchema = z.discriminatedUnion('status', [
  z.object({ status: z.literal('success'), data: z.unknown() }),
  z.object({ status: z.literal('error'), error: z.string() })
]);

Transformations

// Transform during parsing
const lowercaseEmail = z.email().transform(email => email.toLowerCase());

// Coercion (convert types)
const numberFromString = z.coerce.number(); // "42" → 42
const dateFromString = z.coerce.date(); // "2024-01-01" → Date

// Preprocessing
const trimmedString = z.preprocess(
  val => (typeof val === 'string' ? val.trim() : val),
  z.string()
);

Refinements

const passwordSchema = z
  .string()
  .min(8)
  .refine(val => /[A-Z]/.test(val), {
    message: 'Must contain uppercase letter'
  })
  .refine(val => /[0-9]/.test(val), {
    message: 'Must contain number'
  });

// With superRefine for multiple errors
const formSchema = z
  .object({
    password: z.string(),
    confirmPassword: z.string()
  })
  .superRefine((data, ctx) => {
    if (data.password !== data.confirmPassword) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: "Passwords don't match",
        path: ['confirmPassword']
      });
    }
  });

Optional and Nullable

// Optional (T | undefined)
z.string().optional();

// Nullable (T | null)
z.string().nullable();

// Both (T | null | undefined)
z.string().nullish();

// Default values
z.string().default('unknown');
z.number().default(() => Math.random());

Error Handling

// Zod 4: Use 'error' param instead of 'message'
const schema = z.object({
  name: z.string({ error: 'Name must be a string' }),
  email: z.email({ error: 'Invalid email format' }),
  age: z.number().min(18, { error: 'Must be 18 or older' })
});

// Custom error map
const customSchema = z.string({
  error: issue => {
    if (issue.code === 'too_small') {
      return 'String is too short';
    }
    return 'Invalid string';
  }
});

React Hook Form Integration

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

const schema = z.object({
  email: z.email(),
  password: z.string().min(8),
});

type FormData = z.infer<typeof schema>;

function Form() {
  const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
    resolver: zodResolver(schema),
  });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("email")} />
      {errors.email && <span>{errors.email.message}</span>}
    </form>
  );
}

Keywords

zod, validation, schema, typescript, forms, parsing

Skills similaires