Home/
Part XIII — Expert Mode: Systems, Agents, and Automation/40. Advanced Structured Output/40.1 Deep schemas: nested objects and arrays
40.1 Deep schemas: nested objects and arrays
Overview and links for this section of the guide.
Nested Structures
Real-world data has nested objects. Your schemas should reflect this:
const OrderSchema = z.object({
orderId: z.string(),
customer: z.object({
id: z.string(),
name: z.string(),
contact: z.object({
email: z.string().email(),
phone: z.string().optional()
})
}),
items: z.array(z.object({
productId: z.string(),
quantity: z.number().int().positive(),
price: z.object({
unit: z.number(),
total: z.number()
})
})),
shipping: z.object({
address: z.object({
street: z.string(),
city: z.string(),
country: z.string(),
postalCode: z.string()
}),
method: z.enum(['standard', 'express', 'overnight'])
})
});
Array Handling
// Arrays with constraints
const TeamSchema = z.object({
members: z.array(z.object({
name: z.string(),
role: z.enum(['lead', 'engineer', 'designer'])
})).min(1).max(10), // At least 1, at most 10
// Tuple for fixed-length arrays
coordinates: z.tuple([z.number(), z.number()]),
// Non-empty arrays
tags: z.array(z.string()).nonempty()
});
Prompting for Deep Schemas
function buildSchemaPrompt(schema: z.ZodType): string {
return `
Output JSON matching this exact structure:
${JSON.stringify(zodToJsonSchema(schema), null, 2)}
Rules:
- Every required field must be present
- Use null for missing optional fields
- Arrays can be empty unless marked nonempty
- Enum fields must use exact values shown
`;
}