zod
Zod ist eine TypeScript-first Schema Validation Library, die ich in einigen Projekten verwendet habe. Mit der Veröffentlichung von Version 4 wurden einige interessante Verbesserungen ergänzt.
Die komplette Dokumentation zu Zod findest du unter zod.dev.
Was ist Zod eigentlich?
Bevor wir in die Details von v4 einsteigen, kurz zur Einordnung: Zod löst ein Problem, das jeder TypeScript-Entwickler kennt. TypeScript macht zwar zur Compile-Zeit großartiges Static Type Checking, aber zur Runtime ist davon nichts mehr übrig. Sprich: wenn User Input von irgendwo reinkommt (API, Forms, …), dann weißt du nicht, ob die Daten wirklich das Format haben, das du erwartest.
// TypeScript denkt, das ist alles ok...
interface User {
name: string;
age: number;
}
// ...aber zur Runtime kann das hier reinkommen:
const userInput = { name: 42, age: "definitely not a number" };
Zod schließt diese Lücke, indem es Schema Validation zur Runtime ermöglicht und dabei automatisch die TypeScript-Typen ableitet:
import { z } from "zod/v4";
const User = z.object({
name: z.string(),
age: z.number()
});
type User = z.infer<typeof User>; // automatisch abgeleiteter Type
// Sichere Validierung zur Runtime
const result = User.safeParse(userInput);
if (result.success) {
console.log(result.data.name); // Type-safe!
} else {
console.log(result.error); // ZodError mit Details
}
Native JSON Schema Support
Ein Feature, auf das viele gewartet haben: Zod kann jetzt nativ zu JSON Schema konvertieren, ohne externe Libraries wie zod-to-json-schema
:
const User = z.object({
name: z.string(),
email: z.string().email(),
age: z.number().min(18)
});
// Neu in v4: direkte Konvertierung
const jsonSchema = User.toJSON();
Das ist besonders praktisch für API Documentation, Form Builder oder wenn man mit Backend-Systemen arbeitet, die JSON Schema erwarten. Auch viele AI-Modelle unterstützen mittlerweile ein von Zod erstelltes Schema für bspw. Responses.
Verbesserte Error Messages
Die Fehlermeldungen wurden überarbeitet und sind jetzt deutlich informativer:
const schema = z.object({
user: z.object({
profile: z.object({
email: z.string().email()
})
})
});
const result = schema.safeParse({
user: {
profile: {
email: "not-an-email"
}
}
});
if (!result.success) {
console.log(result.error.format());
}
Neue Schema-Features
z.interface() für exakte Object Shapes
Eine der interessantesten Neuerungen ist z.interface()
, das eine exaktere Kontrolle über Object Schemas ermöglicht:
// Mit z.object() werden unbekannte Properties ignoriert
const UserObject = z.object({
name: z.string(),
age: z.number()
});
// Mit z.interface() werden sie strikt validiert
const UserInterface = z.interface({
name: z.string(),
age: z.number()
});
UserInterface.parse({ name: "Stefan", age: 30, extra: "not allowed" });
// Fehler: unbekannte Eigenschaft 'extra'
Bessere Union Types mit Auto-Discriminator
Zod v4 erkennt automatisch Discriminator in Union Types:
const Event = z.union([
z.object({
type: z.literal("click"),
element: z.string()
}),
z.object({
type: z.literal("scroll"),
position: z.number()
})
]);
// Zod erkennt automatisch 'type' als Discriminator
// und kann dadurch effizienter validieren
File Validation
Neu ist auch die native Unterstützung für File Validation im Browser:
const FileSchema = z.file({
maxSize: 1024 * 1024 * 5, // 5MB
types: ["image/jpeg", "image/png"]
});
// Für File Inputs in Forms
const result = FileSchema.safeParse(fileInput.files[0]);
Praxisbeispiel: API Validation
Hier ein kleines Beispiel, wie sich Zod v4 in der Praxis anfühlt:
import { z } from "zod/v4";
// Schema Definition
const CreateUserRequest = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
age: z.number().min(18).max(120),
preferences: z.object({
newsletter: z.boolean().default(false),
theme: z.enum(["light", "dark"]).default("light")
}).optional()
});
// Type Inference
type CreateUserRequest = z.infer<typeof CreateUserRequest>;
// API Handler
async function createUser(req: Request) {
const parseResult = CreateUserRequest.safeParse(await req.json());
if (!parseResult.success) {
return Response.json({
error: "Validation failed",
details: parseResult.error.format()
}, { status: 400 });
}
const userData = parseResult.data; // Type-safe!
// ... User erstellen
}
// JSON Schema für API Docs
const apiDocs = CreateUserRequest.toJSON();