Handle Optional Fields in Zod Schemas from JSON
Learn how to generate Zod schemas with .optional() for fields that may be missing from JSON objects. Understand the difference between optional and required.
Detailed Explanation
Optional Fields in Zod
In JSON, a key is either present or absent. Zod's .optional() modifier allows a field to be undefined or missing entirely from the validated object.
Example JSON
{
"id": 1,
"name": "Alice",
"bio": "Full-stack developer",
"website": "https://alice.dev"
}
Generated Zod Schema (with optional toggle)
import { z } from "zod";
const userSchema = z.object({
id: z.number().int().optional(),
name: z.string().optional(),
bio: z.string().optional(),
website: z.string().optional(),
});
type User = z.infer<typeof userSchema>;
// { id?: number; name?: string; bio?: string; website?: string }
When to Use .optional()
- Partial update endpoints — PATCH requests where any subset of fields can be sent.
- User profile data — Fields like
bio,website, andavatarthat users may not have filled in. - Backward-compatible schemas — New fields added to an API that older clients do not send.
Selective Optional Fields
In practice, you usually want some fields required and others optional. Zod provides .partial() for this:
// All fields optional
const partialUserSchema = userSchema.partial();
// Only specific fields optional
const updateUserSchema = userSchema.partial({
bio: true,
website: true,
});
Default Values
Combine .optional() with .default() to provide fallback values:
const configSchema = z.object({
theme: z.string().optional().default("dark"),
pageSize: z.number().optional().default(20),
showSidebar: z.boolean().optional().default(true),
});
When the field is absent, Zod automatically substitutes the default during parsing. This is particularly useful for configuration objects and user preferences.
.optional() vs .nullable()
.optional()acceptsundefined(field can be absent).nullable()acceptsnull(field present but null)- Chain both for maximum flexibility:
z.string().nullable().optional()
Use Case
You are building a user profile update form where all fields are optional because users can update any subset of their profile data in a single request.