- Published on
How to Omit Fields from Nested Zod Schemas
- Authors
- Name
- Ripal & Zalak
How to Remove Fields from Nested Zod Schemas
Sometimes, while working with Zod schemas in TypeScript, you might need to remove certain fields from a nested schema. Instead of just making them optional, you might want to completely exclude them. Thankfully, Zod provides simple ways to achieve this.
Problem
Imagine you have a schema like this:
import { z } from 'zod'
const schema = z.object({
name: z.number(),
age: z.number(),
data: z.array(
z.object({
id: z.string().optional(),
name: z.string().nonempty().optional(),
})
),
})
Here, the data
field is an array of objects, each containing id
and name
. Now, let’s say you want to remove the name
field from this nested schema.
Solution
omit
1. Using You can use Zod's omit
method to exclude specific fields from a schema. Here’s how:
const updatedSchema = schema.shape.data.element.omit({ name: true }).array()
// Type inference
type UpdatedType = z.infer<typeof updatedSchema>
In this example:
schema.shape.data.element
accesses the schema for the individual items inside thedata
array..omit({ name: true })
removes thename
field from that schema..array()
ensures the updated schema remains an array.
2. Modular Schema Design
A better way to handle schema variations is by breaking them into smaller, reusable parts. For example:
import { z } from 'zod'
// Base schema for data
const baseDataSchema = z.object({
id: z.string().optional(),
value: z.number(),
})
// Extended schema with additional fields
const extendedDataSchema = baseDataSchema.merge(
z.object({
name: z.string().optional(),
})
)
// Schema without 'name'
const noNameSchema = baseDataSchema
// Type inference
type BaseData = z.infer<typeof noNameSchema>
type ExtendedData = z.infer<typeof extendedDataSchema>
This approach allows you to create and manage different versions of the schema effortlessly.
omit
?
Why Use - Clean and Precise: The
omit
method directly removes fields from a schema without making them optional. - Flexibility: Perfect for scenarios where certain fields shouldn’t exist at all.
- Type Safety: Updated schemas automatically infer the correct TypeScript types.
Complete Example
Here’s a complete example combining both approaches:
import { z } from 'zod'
// Original schema
const schema = z.object({
name: z.number(),
age: z.number(),
data: z.array(
z.object({
id: z.string().optional(),
name: z.string().nonempty().optional(),
})
),
})
// Remove 'name' from the nested schema
const updatedSchema = schema.shape.data.element.omit({ name: true }).array()
// Modular schema design
const baseDataSchema = z.object({
id: z.string().optional(),
value: z.number(),
})
const extendedDataSchema = baseDataSchema.merge(z.object({ name: z.string().optional() }))
const noNameSchema = baseDataSchema
// Type inference
type DataWithoutName = z.infer<typeof updatedSchema>
FAQs
Q: Why not just make the field optional? Making a field optional (optional()
) means it can still exist in the schema, but its value can be undefined
. Using omit()
ensures the field is entirely removed.
Q: Can I use this for deeply nested schemas? Yes! You can chain omit()
with other Zod methods to handle complex nested structures.
Q: What if I need to add fields later? Use merge()
to extend schemas with additional fields as required.