Antigravityにコードの追加・修正を依頼するたびに any が増えていく、という経験をしたことはないだろうか。
unknown で受け取るべきAPIレスポンスが any に、型推論できるはずの関数の戻り値が any に、ジェネリクスを使うべき汎用コンポーネントが any[] に——気づけばTypeScriptのstrict設定が形だけのものになっています。
問題の根っこは、AntigravityのようなAIコーディングアシスタントが「動くコードを最短で生成する」最適化をかけているからです。型エラーを回避する最も手っ取り早い手段が any の多用であり、特にコンテキストが不足している状況でその傾向は顕著になります。
Rulesファイルの設定とプロンプト設計の両面から、Antigravityに型安全なTypeScriptを書き続けてもらうための具体的な手法をまとめます。
なぜAntigravityはanyを使うのか
Antigravityが any を生成しやすい状況には、パターンがあります。
コンテキスト不足: 関数の入力・出力の型情報が十分に渡っていないとき、AIは型を推測できず any で逃げる。特に既存のAPIクライアントや型定義ファイルを参照しないまま「このAPIを呼ぶ関数を書いて」と依頼すると発生しやすい。
型エラー修正の要求: 「このコードのTypeScriptエラーを修正して」という指示に対して、エラーの根本原因を解決せず as any や // @ts-ignore で黙らせるケースがあります。速い解決策を優先する設計が影響しています。
外部ライブラリの型が複雑な場合: ジェネリクスが深くネストされたライブラリの型を正確に扱うより、any にキャストしてシンプルに保つ判断がなされることがあります。
これらはいずれも、適切な制約を与えれば回避できます。
Rulesファイルで型安全を強制する
.antigravity/rules の typescript.md に型安全ルールを書いておくと、すべてのセッションで一貫した制約が適用されます。以下は実用的な設定例です:
# TypeScript型安全ルール(必須)
## 絶対禁止
- `any` 型の使用(`unknown` + 型ガードで代替すること)
- `as any` キャスト
- `@ts-ignore` / `@ts-expect-error`(理由をコメントした場合のみ許可)
- 非nullアサーション演算子 `\!` の乱用(明示的なnullチェック後のみ許可)
## 必須パターン
- 外部APIのレスポンスには必ず `unknown` + Zodスキーマを使う
- ジェネリクスが使える場面では積極的に使う
- 型推論できる場合は明示的な型注釈を省略する(冗長な注釈禁止)
- 型エラーは `any` で消さず、型定義の修正か型ガードで解決する
## エラー修正方針
TypeScriptエラーが発生した場合、以下の順序で解決する:
1. 型定義自体の修正
2. 型ガード関数の追加
3. 適切な型アサーション(根拠をコメントで明記)このルールをセットしておくと、Antigravityは型エラーに直面したとき any を使う前に立ち止まる。Antigravity カスタムルール&プロジェクト設定 完全実践ガイドでRulesファイルの詳細な書き方を確認しておくといい。
プロンプト設計:型を守らせる言葉の選び方
Rulesファイルだけでは対処できない場面もあります。特定のタスクをAntigravityに依頼するときのプロンプトが、型安全性に直接影響します。
悪いプロンプトと良いプロンプトの比較
❌ 悪い例:
「fetchUser関数を作って」
✅ 良い例:
「User型を返すfetchUser関数を作って。
- 戻り値は Promise<User>
- APIエラーは Result<User, ApiError> パターンで処理
- レスポンスはZodスキーマでバリデーションする
- UserSchema はすでに src/schemas/user.ts に定義済み(@src/schemas/user.ts)」
悪い例ではAntigravityがUser型を知らないため、レスポンスを any にしがちです。良い例では型情報・エラーハンドリング方針・既存スキーマの場所を明示しています。
@メンションで型定義を渡す
Antigravityに型定義ファイルを明示的に渡すのが最も効果的です:
「@src/types/user.ts @src/types/api.ts を参照して、
これらの型を使ったuserServiceを実装して」
プロンプトエンジニアリングの基本についてはAntigravity プロンプト・エンジニアリング完全ガイドも参照してほしい。
Before/After:実際のコード改善例
実際にAntigravityに同じ機能を依頼したときの比較を見てみよう。
シナリオ: REST APIからユーザーデータを取得する関数の実装
Before(コンテキストなし・ルールなし)
// Antigravityが生成したコード(問題あり)
async function fetchUser(id: string): Promise<any> {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
return data; // anyで返却
}
// 呼び出し側でも型安全が失われる
const user = await fetchUser("123");
console.log(user.naem); // タイポでもエラーが出ないAfter(ルール適用 + 適切なプロンプト)
// @src/schemas/user.ts と @src/types/api.ts を参照して生成
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 };
}
// unknown で受け取って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) } };
}
}
// 呼び出し側でも型安全が保たれる
const result = await fetchUser("123");
if (result.success) {
console.log(result.data.name); // 型補完が効く
// console.log(result.data.naem); // コンパイルエラーになる ✅
}Rulesとプロンプトを適切に設定した結果、Antigravityは自発的にZodスキーマ・Result型・エラーハンドリングをセットで生成するようになります。型の恩恵がコード全体に伝播する設計になっている点も重要です。
よくある落とし穴と対処法
実際に使っていると遭遇しやすい問題と、その対処を挙げておく。
tsconfig.json が strict 未設定
Rulesに型安全ルールを書いても、tsconfig.json で "strict": true が設定されていないと、Antigravityはその設定に合わせたゆるいコードを生成することがあります。compilerOptions に必ず追加しておこう:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true
}
}そのうえで @tsconfig.json をプロンプトに含めると、Antigravityが設定を参照してコードを生成してくれます。
型のバリア突破を要求してしまう指示
「とにかく動かしたい」という意図で書いたプロンプトが、Antigravityに型安全を捨てさせる指示になることがあります。
❌ 「TypeScriptエラーを全部消してとにかく動かして」
✅ 「TypeScriptエラーの根本原因を解決して。anyや@ts-ignoreは使わないで」
前者のような指示を受けたAntigravityは、最も手っ取り早い方法として any キャストを選択する傾向があります。
ジェネリクスを過度に省略させてしまう
便利なユーティリティ関数をAntigravityに書かせると、汎用性のためにジェネリクスを使うべき箇所で具体的な型にハードコードされることがあります。「ジェネリクスで汎用的に実装して」と明示することで改善できます。
全体を振り返って
AntigravityにTypeScriptの型安全を守らせるうえで最も効果的なのは、Rulesファイルで制約を設定することと、型情報を含む丁寧なプロンプトを書くことの組み合わせです。
今日試せる最初のアクションは一つです。.antigravity/rules/typescript.md に any 禁止ルールを1行書いて、次のセッションがどう変わるか確認してみてほしい。
型安全なコードをAntigravityに任せるのは難しい、という当初の認識は変わるはずです。TypeScript + Antigravity で実現する型安全フルスタック開発ガイドとあわせて読むと、プロジェクト全体の型戦略が整理できるはずです。