On this Page
On this Guide
- Lesson 06: Schema Composition with Merge, Extend, Pick, and Omit
- Lesson 07: Refinement, superRefine, and Custom Validators
- Lesson 08: Discriminated Unions and Tagged Types
- Lesson 09: Transforming and Preprocessing Data
- Lesson 10: Working with Records, Maps, Sets, and Enums
- Lesson 11: Async Validation with Promises
- Lesson 12: Reusable Schemas Across Frontend and Backend
Why Schema Composition Matters
In real-world projects, you often reuse and reshape your schemas:
- Share a base schema across multiple variations
- Exclude fields before exposing them in the frontend
- Split logic between database, form validation, and API
Zod provides several helpful tools for this: merge(), extend(), pick(), and omit().
Merging Schemas with merge()
Combines two schemas of type z.object() into one:
const Base = z.object({ id: z.string() });
const Profile = z.object({ name: z.string() });
const User = Base.merge(Profile);
The result:
User.parse({ id: "123", name: "Alice" }); // ✅
> ⚠️ Note: Conflicts will favor the second schema (Profile in this case).
Adding Fields with extend()
Use extend() to add more fields to an existing schema:
const User = z.object({ name: z.string() });
const Admin = User.extend({
role: z.literal("admin"),
});
This preserves the original schema and creates a new one with additional fields.
Selecting Fields with pick()
If you only want part of a schema (e.g. just id and email), use pick():
const FullUser = z.object({
id: z.string(),
name: z.string(),
email: z.string(),
});
const PublicUser = FullUser.pick({ id: true, email: true });
Now PublicUser only accepts { id, email }.
Removing Fields with omit()
The opposite of pick(). Remove sensitive/internal fields like passwords:
const DBUser = z.object({
id: z.string(),
email: z.string(),
password: z.string(),
});
const SafeUser = DBUser.omit({ password: true });
SafeUser no longer allows password to appear.
Summary
- Use
.merge()to combine schemas - Use
.extend()to add fields cleanly - Use
.pick()and.omit()to reshape schemas for different use cases
Next up: Lesson 7 – Refinement, superRefine, and Custom Validators for powerful validation logic beyond types.
Master the Code, Be the Guru!