Master advanced Zod validation patterns for Google Antigravity IDE type-safe applications
# Zod Validation Advanced Patterns for Google Antigravity IDE
Build bulletproof validation with Zod using Google Antigravity IDE. This comprehensive guide covers complex schemas, transforms, refinements, and integration patterns for runtime type safety.
## Complex Schema Patterns
```typescript
// src/schemas/user.ts
import { z } from "zod";
const emailSchema = z.string().email("Invalid email format").toLowerCase().trim();
const passwordSchema = z.string()
.min(8, "Password must be at least 8 characters")
.regex(/[A-Z]/, "Must contain uppercase letter")
.regex(/[a-z]/, "Must contain lowercase letter")
.regex(/[0-9]/, "Must contain number")
.regex(/[^A-Za-z0-9]/, "Must contain special character");
export const userRegistrationSchema = z
.object({
email: emailSchema,
password: passwordSchema,
confirmPassword: z.string(),
name: z.string().min(2).max(100),
dateOfBirth: z.coerce.date().refine(
(date) => {
const age = Math.floor((Date.now() - date.getTime()) / (365.25 * 24 * 60 * 60 * 1000));
return age >= 13;
},
{ message: "Must be at least 13 years old" }
),
role: z.enum(["user", "admin", "moderator"]).default("user"),
preferences: z.object({
newsletter: z.boolean().default(true),
notifications: z.object({
email: z.boolean().default(true),
push: z.boolean().default(false),
}),
theme: z.enum(["light", "dark", "system"]).default("system"),
}).default({}),
})
.refine((data) => data.password === data.confirmPassword, {
message: "Passwords do not match",
path: ["confirmPassword"],
})
.transform((data) => {
const { confirmPassword, ...rest } = data;
return rest;
});
export type UserRegistration = z.infer<typeof userRegistrationSchema>;
```
## Discriminated Unions
```typescript
// Polymorphic notification schema
const baseNotification = z.object({
id: z.string().uuid(),
createdAt: z.coerce.date(),
read: z.boolean().default(false),
});
export const notificationSchema = z.discriminatedUnion("type", [
baseNotification.extend({
type: z.literal("message"),
senderId: z.string().uuid(),
content: z.string(),
}),
baseNotification.extend({
type: z.literal("follow"),
followerId: z.string().uuid(),
}),
baseNotification.extend({
type: z.literal("like"),
postId: z.string().uuid(),
likerId: z.string().uuid(),
}),
baseNotification.extend({
type: z.literal("system"),
title: z.string(),
message: z.string(),
action: z.object({
label: z.string(),
url: z.string().url(),
}).optional(),
}),
]);
```
## API Request Validation
```typescript
// src/schemas/api.ts
export const paginationSchema = z.object({
page: z.coerce.number().int().positive().default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
sortBy: z.string().optional(),
sortOrder: z.enum(["asc", "desc"]).default("desc"),
});
export const searchSchema = paginationSchema.extend({
q: z.string().min(1).max(200).optional(),
filters: z.string()
.transform((str) => {
try { return JSON.parse(str); } catch { return {}; }
})
.pipe(z.record(z.union([z.string(), z.number(), z.boolean()])))
.optional(),
});
export const fileUploadSchema = z.object({
file: z.custom<File>((val) => val instanceof File, "Must be a file")
.refine((file) => file.size <= 10 * 1024 * 1024, "File must be less than 10MB")
.refine(
(file) => ["image/jpeg", "image/png", "application/pdf"].includes(file.type),
"Invalid file type"
),
});
export function createResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {
return z.object({
success: z.boolean(),
data: dataSchema,
meta: z.object({
total: z.number().optional(),
page: z.number().optional(),
}).optional(),
});
}
```
## Server Action Validation
```typescript
// src/actions/user.ts
"use server";
import { z } from "zod";
import { userRegistrationSchema } from "@/schemas/user";
type ActionResult<T> = { success: true; data: T } | { success: false; errors: z.ZodIssue[] };
export async function registerUser(formData: FormData): Promise<ActionResult<{ userId: string }>> {
const rawData = Object.fromEntries(formData.entries());
const result = userRegistrationSchema.safeParse({
...rawData,
preferences: rawData.preferences ? JSON.parse(rawData.preferences as string) : undefined,
});
if (!result.success) {
return { success: false, errors: result.error.issues };
}
const user = await createUser(result.data);
return { success: true, data: { userId: user.id } };
}
```
## Best Practices for Google Antigravity IDE
When using Zod with Google Antigravity, create reusable base schemas for common patterns. Use discriminated unions for polymorphic data. Implement transforms for data normalization. Add refinements for complex business rules. Let Gemini 3 generate schemas from TypeScript interfaces.
Google Antigravity excels at inferring Zod schemas from existing data structures.This Zod prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their zod implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For Zod projects, consider mentioning your framework version, coding style, and any specific libraries you're using.