Ask Antigravity to add a feature, and suddenly your codebase has three new any types. Ask it to fix a TypeScript error, and it slaps on as any and calls it done.
If this sounds familiar, you're not dealing with a flaw in Antigravity — you're dealing with a calibration problem. AI coding assistants are optimized to produce working code as fast as possible, and any is the fastest way to silence a type error. Without explicit constraints, that's the path Antigravity will take.
This guide covers two complementary approaches: configuring Rules files so that type-safe behavior is the default, and designing prompts that give Antigravity the context it needs to infer types correctly rather than reaching for any.
Why Antigravity Reaches for any
The pattern isn't random. Antigravity generates any most often in three situations:
Missing context: When the function's input and output types aren't visible in the conversation, Antigravity can't infer them. Asking "write a function that calls this API" without providing the response type schema almost always yields an any-typed return value.
Error suppression requests: Telling Antigravity to "fix the TypeScript errors" without specifying how invites shortcuts. Wrapping the problematic line in as any resolves the error with minimal code change — exactly the kind of solution an AI optimizing for brevity might choose.
Complex generic types: When a library's type signature involves deeply nested generics, Antigravity may cast to any to sidestep the complexity rather than correctly parameterizing the type.
All three are avoidable with the right setup.
Enforcing Type Safety Through Rules Files
A .antigravity/rules/typescript.md file applies constraints globally across every session in your project. Here's a practical starting configuration:
# TypeScript Type Safety Rules (Required)
## Strictly Prohibited
- The `any` type (use `unknown` + type guards instead)
- `as any` casts
- `@ts-ignore` and `@ts-expect-error` without an explanatory comment
- Excessive non-null assertions `\!` (only allowed after explicit null checks)
## Required Patterns
- Validate external API responses using `unknown` + Zod schemas
- Use generics wherever a function operates on multiple types
- Prefer type inference over redundant explicit annotations
- Resolve type errors by fixing the type definition or adding a type guard — never by widening to `any`
## Error Resolution Priority
When encountering a TypeScript error:
1. Fix the underlying type definition
2. Add a type guard function
3. Use a justified type assertion (with an inline comment explaining why)With this in place, Antigravity will pause before generating any and look for a typed alternative. For a deeper look at structuring Rules files across a project, see the Antigravity Custom Rules & Project Configuration Mastery Guide.
Prompt Design: Giving Antigravity the Types It Needs
Rules files set the constraint. Prompt design provides the context. Together, they eliminate almost all cases of unintended any.
Contrast: vague vs. context-rich prompts
❌ Vague prompt:
"Write a fetchUser function"
✅ Context-rich prompt:
"Write a fetchUser function with these constraints:
- Return type: Promise<User>
- Handle API errors using a Result<User, ApiError> pattern
- Validate the response with the Zod schema in @src/schemas/user.ts
- The User type is defined in @src/types/user.ts"
The vague version leaves Antigravity guessing about the User type, so it defaults to any. The second version provides the type contracts upfront — Antigravity no longer needs to guess.
Using @mentions to share type definitions
The most reliable way to ground Antigravity in your type system is to pass your type files directly:
"Referring to @src/types/user.ts and @src/types/api.ts,
implement a userService module that uses these types throughout"
For broader prompt strategies, the Antigravity Prompt Engineering Guide covers the full pattern in detail.
Before and After: A Real Example
The same feature request, with and without proper setup:
Scenario: Fetch user data from a REST API endpoint.
Before (no context, no Rules)
// Antigravity-generated code — problematic
async function fetchUser(id: string): Promise<any> {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
return data; // typed as any — type safety lost downstream
}
// The caller inherits the any type
const user = await fetchUser("123");
console.log(user.naem); // typo — no compiler errorAfter (Rules applied + context-rich prompt)
// Generated with @src/schemas/user.ts and @src/types/api.ts in context
import { z } from "zod";
const UserSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
createdAt: z.string().datetime(),
});
type User = z.infer<typeof UserSchema>;
type ApiError = {
code: string;
message: string;
};
type Result<T, E> = { success: true; data: T } | { success: false; error: E };
async function fetchUser(id: string): Promise<Result<User, ApiError>> {
try {
const response = await fetch(`/api/users/${id}`);
if (\!response.ok) {
const error: ApiError = await response.json();
return { success: false, error };
}
// Receive as unknown, validate with Zod
const rawData: unknown = await response.json();
const parsed = UserSchema.safeParse(rawData);
if (\!parsed.success) {
return {
success: false,
error: { code: "PARSE_ERROR", message: parsed.error.message },
};
}
return { success: true, data: parsed.data };
} catch (e) {
return {
success: false,
error: { code: "NETWORK_ERROR", message: String(e) },
};
}
}
// Caller benefits from full type safety
const result = await fetchUser("123");
if (result.success) {
console.log(result.data.name); // autocomplete works
// console.log(result.data.naem); // compile error ✅
}With Rules and a context-rich prompt, Antigravity generates the Zod schema, Result type, and full error handling as a unit. The type safety propagates outward to every call site automatically.
Common Pitfalls
A few issues that come up frequently in real projects:
tsconfig.json without strict: true
Rules file constraints work best when the compiler enforces them too. Without "strict": true in tsconfig.json, Antigravity calibrates its output to the actual compiler settings — not to your ideal. Add the strictest settings your project can handle:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true
}
}Including @tsconfig.json in your prompts signals to Antigravity to respect these settings when generating code.
Prompts that implicitly invite any
A prompt like "just make the TypeScript errors go away" is an invitation to use any. Be explicit about the constraint:
❌ "Fix all the TypeScript errors however you can"
✅ "Fix the TypeScript errors without using any, as any, or @ts-ignore"
Under-specified generic functions
When writing utility functions, Antigravity sometimes hardcodes a specific type where a generic would be more appropriate. Adding "implement this as a generic function" or "use generics so this works with any type T" explicitly surfaces that requirement.
Where to Go From Here
The most effective change you can make today is adding a single-line any prohibition to .antigravity/rules/typescript.md and watching the next session's output shift. The difference in code quality is usually immediate.
For a broader view of how TypeScript type design interacts with Antigravity across a full-stack project, the TypeScript + Antigravity Type-Safe Full-Stack Development Guide is the natural next step.