Combining TypeScript with Antigravity gives you the best of both worlds: the speed of AI-generated code and the safety of a strict type system. This guide walks you through building a type-safe full-stack application using Antigravity's agent capabilities alongside TypeScript's type system and Zod runtime validation.
What You'll Learn
- How Antigravity handles TypeScript projects and where to guide it
- Building type-safe API routes and frontend components step-by-step
- Integrating Zod schemas for runtime validation with type inference
- Effective TypeScript-focused prompting strategies for Antigravity agents
- Diagnosing and fixing common type errors with agent assistance
Who this is for: Developers with working TypeScript knowledge who want to use Antigravity at a professional level.
Prerequisites and Environment Setup
You'll need the following tools ready before starting:
- Google Antigravity (version 1.20 or later) — download at antigravity.google/download
- Node.js 20 or later
- TypeScript 5.3 or later
Once Antigravity is running, create a new workspace and use the following prompt to scaffold the project:
Create a TypeScript full-stack starter project.
Use Next.js 15 App Router, Zod, and Tailwind CSS.
Include type-safe API routes and form validation setup.
The agent will automatically generate the folder structure, package.json, and tsconfig.json.
TypeScript Project Structure and Type Design
Here's the structure Antigravity typically generates for a TypeScript full-stack app:
my-app/
├── src/
│ ├── app/
│ │ ├── api/
│ │ │ └── users/
│ │ │ └── route.ts ← Type-safe API route
│ │ └── page.tsx
│ ├── lib/
│ │ └── schemas.ts ← Zod schema definitions
│ └── types/
│ └── index.ts ← Shared type definitions
├── tsconfig.json
└── package.json
Defining Shared Types
Prompt the agent to create shared types in src/types/index.ts:
Define the following types in src/types/index.ts:
- User (id, name, email, createdAt)
- CreateUserInput (name, email)
- ApiResponse<T> (data, error, success)
These will be shared across API routes and frontend components.
The generated shared types look like this:
// src/types/index.ts
export interface User {
id: string;
name: string;
email: string;
createdAt: Date;
}
export interface CreateUserInput {
name: string;
email: string;
}
export interface ApiResponse<T> {
data: T | null;
error: string | null;
success: boolean;
}Integrating Zod for Runtime Validation
TypeScript's type checking only runs at compile time — it can't validate data coming in from external sources at runtime. That's where Zod comes in. Combining Zod schemas with TypeScript type inference gives you end-to-end safety.
Prompt the agent:
Create Zod schemas in src/lib/schemas.ts:
- CreateUserSchema (name: 2-50 chars, email: valid format required)
- Use z.infer to derive the CreateUserInput type automatically
Generated schema:
// src/lib/schemas.ts
import { z } from "zod";
export const CreateUserSchema = z.object({
name: z.string()
.min(2, "Name must be at least 2 characters")
.max(50, "Name cannot exceed 50 characters"),
email: z.string()
.email("Please enter a valid email address"),
});
// Auto-derive TypeScript type from Zod schema
export type CreateUserInput = z.infer<typeof CreateUserSchema>;
// => { name: string; email: string; }Using z.infer means any change to the schema automatically propagates to the type — no manual sync required.
Building Type-Safe API Routes
Here's how to wire up Zod validation inside a Next.js App Router API route:
// src/app/api/users/route.ts
import { NextRequest, NextResponse } from "next/server";
import { CreateUserSchema } from "@/lib/schemas";
import type { ApiResponse, User } from "@/types";
export async function POST(
request: NextRequest
): Promise<NextResponse<ApiResponse<User>>> {
try {
const body = await request.json();
// Runtime validation with Zod
const result = CreateUserSchema.safeParse(body);
if (!result.success) {
return NextResponse.json(
{
data: null,
error: result.error.errors[0].message,
success: false,
},
{ status: 400 }
);
}
// result.data is fully typed as CreateUserInput after validation
const { name, email } = result.data;
const newUser: User = {
id: crypto.randomUUID(),
name,
email,
createdAt: new Date(),
};
return NextResponse.json({ data: newUser, error: null, success: true });
} catch {
return NextResponse.json(
{ data: null, error: "Internal server error", success: false },
{ status: 500 }
);
}
}Annotating the return type as ApiResponse<User> ensures the frontend gets consistent, predictable data shapes.
Prompting Strategies for TypeScript Code Generation
Getting the agent to produce high-quality TypeScript requires being specific about type constraints in your prompts.
Prompting for Type Inference
Create a user form component using React Hook Form + Zod resolver.
- Connect CreateUserSchema via zodResolver
- Let UseFormReturn infer the errors object type automatically
- The submit handler should receive ApiResponse<User> and handle it with full type safety
Prompting to Fix Type Errors
Fix this TypeScript error:
"Type 'string | undefined' is not assignable to type 'string'"
Identify where user.email could be undefined,
and use a proper type guard instead of non-null assertion (!).
AGENTS.md for TypeScript Conventions
Create AGENTS.md at the project root to encode your TypeScript standards. Antigravity 1.20+ reads this file alongside GEMINI.md:
# AGENTS.md
## TypeScript Rules
- Never use `any` type. Use `unknown` with type guards instead.
- Omit explicit type annotations where TypeScript can infer the type.
- Derive types from Zod schemas using `z.infer` — avoid duplicate type definitions.
- Prefer Optional Chaining (`?.`) over null checks.
- Always wrap API responses in `ApiResponse<T>`.Common Type Errors and Agent-Assisted Fixes
Error 1: Property 'X' does not exist on type 'Y'
This usually means a property name mismatch between your type definition and actual usage.
Agent prompt:
Fix TypeScript error "Property 'userId' does not exist on type 'User'".
Check the User type definition and decide on a consistent property name (userId or id),
then apply the fix across all affected files.
The agent will scan across files and apply a consistent rename.
Error 2: Async Function Return Type Inference
// ❌ Problem: return type infers as Promise<any>
async function fetchUser(id: string) {
const res = await fetch(`/api/users/${id}`);
return res.json(); // widens to Promise<any>
}
// ✅ Fix: explicit return type annotation
async function fetchUser(id: string): Promise<ApiResponse<User>> {
const res = await fetch(`/api/users/${id}`);
return res.json() as Promise<ApiResponse<User>>;
}Prompt the agent:
Add explicit return type Promise<ApiResponse<User>> to fetchUser,
and ensure callers also benefit from the type inference downstream.
Error 3: Enum vs. Union Type
When the agent generates enum types, consider having it switch to Union Types for better tree-shaking:
Refactor the generated enum to a Union Type:
status: "pending" | "active" | "inactive"
Reason: improved bundle size and more accurate type narrowing.
Advanced: Automating Type Consistency Checks with Agents
In larger projects, backend and frontend types can drift apart over time. You can use Antigravity agents to catch mismatches automatically:
Scan src/types/index.ts and all src/app/api/**/route.ts files.
List every type inconsistency (property name mismatches, type differences).
Automatically fix any inconsistencies you find.
Using Manager Surface (multi-agent mode), you can run a type-check agent and a test agent in parallel — effectively running a local CI check before committing.
For more on building full-stack apps, see Next.js + Antigravity Full-Stack Development and Backend with Supabase + Antigravity.
Looking back
TypeScript and Antigravity are a natural fit: AI agents handle the boilerplate and initial scaffolding, while TypeScript's type system ensures that generated code stays correct and maintainable. Here are the key takeaways:
- Use Zod +
z.inferto manage schemas and types from a single source of truth - Encode TypeScript rules in
AGENTS.mdto improve agent output quality - Add explicit return type annotations to API routes to maintain frontend-backend type consistency
- Use Manager Surface to run type checks and tests in parallel, accelerating development
Ready to ship? Check out the Vercel + Antigravity Deployment Guide to take your type-safe app to production.