メインコンテンツまでスキップ

Cursor TypeScript:型安全性と AI 支援開発

Cursor TypeScript

TypeScript は強力な型安全性を追加し、Cursor の AI は複雑な型を生成し、改善を提案し、手作業よりはるかに速く型エラーを捉えることができます。このガイドでは、TypeScript のベストプラクティス、高度なパターン、AI 支援ワークフローについて説明します。

前提条件​

開始する前に:

  • Cursor をインストール(最新バージョンを推奨)
  • TypeScript の基礎(型、インターフェース、ジェネリクス)に精通していること
  • tsconfig.json が設定されたプロジェクト

Cursor での TypeScript セットアップ​

tsconfig.json のベストプラクティス​

{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

Cursor の TypeScript 設定​

// .vscode/settings.json
{
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.suggest.autoImports": true,
"typescript.inlayHints.parameterNames.enabled": "all",
"typescript.inlayHints.variableTypes.enabled": true
}

AI を使用した型の生成​

API レスポンスからのインターフェース生成​

JSON レスポンスを貼り付けて、Cursor に型を生成させます:

これらの API レスポンスの TypeScript インターフェースを生成してください:
[JSON を貼り付け]

Cursor が生成:

interface User {
id: number;
name: string;
email: string;
role: 'admin' | 'user' | 'guest';
profile: {
avatar: string;
bio: string | null;
};
createdAt: string; // ISO 日付
}

interface ApiResponse<T> {
data: T;
meta: {
page: number;
total: number;
};
}

関数シグネチャからの型推論​

// Cursor に設定オブジェクトに型を付けるよう依頼
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retries: 3,
};

// Cursor の提案:
interface ApiConfig {
readonly apiUrl: string;
readonly timeout: number;
readonly retries: number;
}

高度な型パターン​

条件型​

// 型に基づく API レスポンスラッパー
type ApiResponse<T> = T extends Array<infer U>
? { data: T; count: number }
: { data: T };

// 使用
const usersResponse: ApiResponse<User[]> = {
data: users,
count: users.length,
};

const userResponse: ApiResponse<User> = {
data: user,
};

テンプレートリテラル型​

type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type Endpoint = `/api/${string}`;

type ApiRoute = `${HttpMethod} ${Endpoint}`;
// => "GET /api/users" | "POST /api/users" | ...

型ガード​

// ユニオン型を絞り込む
function isString(value: unknown): value is string {
return typeof value === 'string';
}

function isError(error: unknown): error is Error {
return error instanceof Error;
}

// 使用
function handleError(error: unknown) {
if (isError(error)) {
console.error(error.message); // Error 型
} else {
console.error(String(error));
}
}

ジェネリクスパターン​

型安全な Hooks​

// ジェネリクスを使用した useLocalStorage
function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = useState<T>(() => {
const stored = localStorage.getItem(key);
return stored ? (JSON.parse(stored) as T) : initialValue;
});

const updateValue = useCallback(
(newValue: T | ((prev: T) => T)) => {
setValue((prev) => {
const next = newValue instanceof Function ? newValue(prev) : newValue;
localStorage.setItem(key, JSON.stringify(next));
return next;
});
},
[key]
);

return [value, updateValue] as const;
}

// 使用
const [user, setUser] = useLocalStorage<User>('user', defaultUser);

型安全な API クライアント​

interface ApiClient {
get<T>(url: string): Promise<T>;
post<T, D>(url: string, data: D): Promise<T>;
put<T, D>(url: string, data: D): Promise<T>;
delete<T>(url: string): Promise<T>;
}

// 実装は型推論を提供
const user = await api.get<User>('/users/1');
const created = await api.post<User, CreateUserDTO>('/users', newUser);

型推論のベストプラクティス​

パターン推奨
戻り値単純な戻り値は TypeScript に推論させる
関数引数常に明示的に型を付ける
配列空の配列には as const を使用
設定オブジェクトモジュールレベルで型を付ける
React Props常にインターフェースを使用

一般的な TypeScript パターン​

Branded Types​

type UserId = string & { __brand: 'UserId' };
type PostId = string & { __brand: 'PostId' };

function createUserId(id: string): UserId {
return id as UserId;
}

// ID の混同を防ぐ
function fetchUser(id: UserId) { ... }
function fetchPost(id: PostId) { ... }

Result 型​

type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };

async function fetchUser(id: string): Promise<Result<User>> {
try {
const user = await db.user.findById(id);
if (!user) {
return { success: false, error: new Error('User not found') };
}
return { success: true, data: user };
} catch (error) {
return { success: false, error: error as Error };
}
}

Cursor を使用した型のデバッグ​

型エラーの分析​

この型エラーを説明し、修正を提案してください:
[エラーを貼り付け]

型テストの生成​

// 型チャレンジを使用して型をテスト
type Assert<T, U> = T extends U ? true : false;

// テスト
type Test1 = Assert<string, string>; // true
type Test2 = Assert<number, string>; // false

関連リソース​

最終更新:2025 年 7 月