導入
「JavaScriptは書けるけれど、TypeScriptは型が難しくて挫折した」――こんな声をよく聞きます。確かに、初学者にとってTypeScriptのGenericsやConditional Typesは壁になりがちです。しかしClaudeCodeを使えば、その壁を一気に超えられます。型定義の自動生成、tsconfig.jsonの最適化、型エラーの自動解決、ジェネリクスを使った高度なAPIの設計まで、自然言語で依頼するだけで進められるからです。本記事では、TypeScriptの基礎を踏まえた上で、ClaudeCodeを使った実践的な開発フローを8,000字以上のボリュームで解説します。読み終える頃には、型安全な開発の心地よさを実感できるはずです。
結論
結論からお伝えします。TypeScript開発はClaudeCodeとの相性が抜群です。理由は、TypeScriptの強みである「型情報」がClaudeCodeにとって最高のコンテキストになるからです。型を見れば関数の意図がわかり、間違った使い方を即座に指摘でき、リファクタリングも安全に行えます。重要なポイントは三つです。第一に、strict: trueを必ず有効にすること。これは型安全の出発点であり、ClaudeCodeも厳格モード前提でコードを生成します。第二に、anyを許さない姿勢を持つこと。曖昧な型はバグの温床になります。第三に、ClaudeCodeに型を「設計させる」のではなく「実装の意図から導かせる」こと。「ユーザーオブジェクトを表す型を作って」ではなく「ユーザー登録APIのレスポンスを表す型を、このスキーマに沿って作って」と具体的に依頼することで、適切な型が手に入ります。Cloudflare Workers+Next.jsの社内標準スタックでも、TypeScriptは必須です。本記事の内容を実践に組み込み、型安全な開発体制を整えていきましょう。
TypeScriptとは何か?
TypeScriptは、Microsoftが開発しているプログラミング言語で、JavaScriptに「型」の概念を加えたものです。コンパイル時に型をチェックし、実行前にミスを発見できるのが最大の特徴です。最終的にはJavaScriptに変換されて実行されるので、Node.jsやブラウザがTypeScriptに対応している必要はありません。
型をつけるメリットは大きく三つあります。第一に、エディタの補完が強力になること。VSCodeは型情報から「このオブジェクトには何のプロパティがあるか」「この関数は何を返すか」を即座に表示してくれます。第二に、リファクタリングが安全になること。関数のシグネチャを変更すると、影響箇所がコンパイルエラーとして列挙されます。第三に、ドキュメントとしての役割を果たすこと。型を見れば仕様が分かるので、コメントを書く量が減ります。
2026年現在、新規のNode.js・フロントエンドプロジェクトの大半はTypeScriptで始まります。Next.js、Hono、Cloudflare Workers SDKもTypeScriptファーストで設計されており、JavaScriptで書くよりむしろ簡単に始められる時代になりました。
ClaudeCodeでTypeScript環境を構築する
新規プロジェクトのセットアップから始めましょう。ClaudeCodeに依頼します。
新しいNode.jsプロジェクトをTypeScriptで初期化してください。tsconfig.jsonはstrict: trueで設定し、ESM、Node.js 20向け、出力先はdist、ts-nodeでの実行も可能にしてください。
ClaudeCodeは以下を行います。
npm init -yでpackage.json生成npm install --save-dev typescript ts-node @types/nodenpx tsc --initでtsconfig.json生成- 設定をstrict寄りに調整
package.jsonのscriptsにbuild、dev、type-checkを追加
生成されるtsconfig.jsonの例:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
noUncheckedIndexedAccess: trueは2026年では必ず有効にしたい設定です。配列やオブジェクトのインデックスアクセスをT | undefinedとして扱ってくれるので、nullチェック漏れによるランタイムエラーを大幅に減らせます。
基本の型をマスターする
TypeScriptの基本型は次の通りです。
let name: string = 'Taro';
let age: number = 30;
let isActive: boolean = true;
let tags: string[] = ['admin', 'user'];
let scores: number[] = [80, 90, 95];
// オブジェクト型
type User = {
id: number;
name: string;
email: string;
isPremium: boolean;
};
const user: User = {
id: 1,
name: 'Taro',
email: 'taro@example.com',
isPremium: false,
};
// 関数の型
function greet(user: User): string {
return `Hello, ${user.name}`;
}
// Union型(複数の型のどれか)
type Status = 'pending' | 'active' | 'banned';
let userStatus: Status = 'active';
// Optional(あってもなくても良い)
type Profile = {
bio?: string;
avatarUrl?: string;
};
これらをClaudeCodeに「実装の意図」を伝えて生成してもらうのが効率的です。
ユーザー管理APIのレスポンス型を作成してください。ユーザーはid(数値)、名前、メール、ステータス(pending/active/banned)、プロフィール(任意でbioとavatarUrl)を持ちます。
型定義の自動生成
実務では、JSONレスポンスから型を作る場面が頻繁にあります。quicktypeのようなツールもありますが、ClaudeCodeに直接サンプルJSONを渡すのが手軽です。
以下のJSONレスポンスから、TypeScriptの型定義を生成してください。日時はDate型ではなくISO 8601文字列のままにしてください。
{
"id": 123,
"title": "blog post",
"createdAt": "2026-05-12T10:00:00Z",
"author": {
"id": 1,
"name": "Taro"
},
"tags": ["typescript", "claudecode"]
}
生成例:
export type BlogPostResponse = {
id: number;
title: string;
createdAt: string; // ISO 8601
author: {
id: number;
name: string;
};
tags: string[];
};
OpenAPI仕様書(Swagger)からTypeScript型を一括生成したい場合は、openapi-typescriptなどのツールをClaudeCodeに導入してもらいましょう。
このプロジェクトにopenapi-typescriptを導入し、./openapi.yamlからsrc/types/api.tsへの型生成スクリプトを追加してください。
ジェネリクスで再利用性の高い型を作る
ジェネリクスは「型をパラメータ化する」仕組みです。たとえばAPIレスポンスの共通形式を表現するときに重宝します。
type ApiResponse<T> = {
success: boolean;
data: T;
error?: string;
};
type UserResponse = ApiResponse<User>;
type PostListResponse = ApiResponse<Post[]>;
ClaudeCodeに依頼するときは、「共通形式」を意識して伝えるとうまく作ってくれます。
APIレスポンスの共通形式ApiResponse<T>を作成してください。successフラグ、data(ジェネリクスT)、エラー時のerror(任意の文字列)、ページネーション時のpagination(任意、totalとpageとperPageを持つ)を含めてください。
型エラーの解決
TypeScriptを書いていて遭遇する代表的なエラーをいくつか見ておきましょう。
エラー1:Object is possibly 'undefined'
const users: User[] = [];
console.log(users[0].name); // ❌ users[0]がundefinedかもしれない
対策:
const first = users[0];
if (first) {
console.log(first.name); // ✅
}
// または
console.log(users[0]?.name);
エラー2:Type 'string | undefined' is not assignable to type 'string'
function send(message: string) { /* ... */ }
const msg: string | undefined = process.env.MESSAGE;
send(msg); // ❌
対策:環境変数のvalidationを書く(前述のzod推奨)か、デフォルト値を入れる。
エラー3:Property 'x' does not exist on type ...
オブジェクトの型が広すぎる、もしくは絞り込みが不足しています。in演算子やtypeofで型ガードを書きましょう。
ClaudeCodeに以下のように丸投げできるのも強みです。
以下の型エラーが出ています。原因と修正方法を教えてください。可能なら修正コードも提示してください。
(ここにtscの出力を貼り付け)
型ガードと判別可能なユニオン
複雑なドメインを扱うときに役立つのが「判別可能なユニオン(discriminated union)」です。
type Result<T> =
| { kind: 'success'; value: T }
| { kind: 'error'; message: string };
function handle(result: Result<User>) {
if (result.kind === 'success') {
console.log(result.value.name); // 型が絞り込まれる
} else {
console.error(result.message);
}
}
ClaudeCodeに以下のように依頼すれば、戻り値の表現を例外ではなくResult型に統一する設計に変えてくれます。
fetchUserなどのAPI呼び出し関数の戻り値を、例外を投げる方式から判別可能なユニオンのResult型を返す方式にリファクタリングしてください。
ClaudeCodeでの型リファクタリング
「動くけど読みにくい型」を改善するのもClaudeCodeの得意分野です。
ビフォー:
function process(data: any): any {
if (data.type === 'user') {
return { name: data.name.toUpperCase() };
} else {
return { error: 'unknown' };
}
}
依頼:
このprocess関数を、anyを使わずに型安全な実装に書き換えてください。引数と戻り値の両方で判別可能なユニオンを使ってください。
アフター:
type Input =
| { type: 'user'; name: string }
| { type: 'admin'; name: string; role: string };
type Output =
| { ok: true; name: string }
| { ok: false; error: string };
function process(data: Input): Output {
if (data.type === 'user') {
return { ok: true, name: data.name.toUpperCase() };
}
return { ok: false, error: 'unknown' };
}
Cloudflare Workers + TypeScriptの実践
社内標準のCloudflare Workersでは、TypeScriptは事実上の必須です。wrangler typesコマンドで、wrangler.jsoncの設定からEnv型を自動生成できます。
npx wrangler types
生成されたworker-configuration.d.tsに基づいて、Honoのコードは次のように書けます。
import { Hono } from 'hono';
type Bindings = {
DB: D1Database;
ANTHROPIC_API_KEY: string;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/users/:id', async (c) => {
const id = c.req.param('id');
const user = await c.env.DB
.prepare('SELECT * FROM users WHERE id = ?')
.bind(id)
.first<{ id: number; name: string }>();
if (!user) {
return c.json({ error: 'User not found' }, 404);
}
return c.json(user);
});
export default app;
first<T>()にジェネリクスを指定することで、D1から取得した値も型付きで扱えます。
zodでランタイムバリデーション
TypeScriptの型はコンパイル時にしか効きません。実行時の入力検証にはzodを併用するのが定番です。
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(1).max(50),
email: z.string().email(),
age: z.number().int().min(0).max(150),
});
type CreateUserInput = z.infer<typeof CreateUserSchema>;
function createUser(input: unknown): CreateUserInput {
return CreateUserSchema.parse(input); // 失敗すると例外
}
ClaudeCodeに「APIの入力をzodで検証するスキーマと、対応するTypeScript型をinferで導出して」と依頼すれば、スキーマと型を同時に得られます。
実践チュートリアル:実プロンプト例集
プロンプト例1:tsconfigの厳格化
現在のtsconfig.jsonをよりstrictな構成に書き換えてください。noUncheckedIndexedAccessやexactOptionalPropertyTypesも有効化し、必要な箇所のコード修正案も併せて提示してください。
プロンプト例2:JSONからの型生成
以下のJSONレスポンスから型を生成してください。配列の要素はTypeArrayItemとして個別に定義してください。
(ここにJSONを貼り付け)
プロンプト例3:anyの一掃
プロジェクト全体からanyを排除してください。意味のある型に置き換え、判断に迷う場合はunknown + 型ガードで対応してください。
プロンプト例4:型エラーの一括解決
npm run type-checkで以下のエラーが出ています。優先度順に修正方針を提案し、可能なものから実装してください。
(ここにエラー一覧を貼り付け)
プロンプト例5:zodスキーマ自動生成
src/types/api.tsのTypeScript型から、対応するzodスキーマをsrc/schemas/api.tsに自動生成してください。z.inferで元の型と完全に一致させてください。
プロンプト例6:ジェネリクスの導入
このRepository<User>、Repository<Post>のような繰り返しを、ジェネリクスを使った汎用Repository<T>クラスにリファクタリングしてください。
プロンプト例7:Cloudflare Workers用Env型生成
wrangler.jsoncに新しいシークレットANTHROPIC_API_KEYとD1バインディングDBを追加しました。wrangler typesを実行する手順と、Honoコードで型安全に使う方法を教えてください。
FAQ
Q1. TypeScriptは初学者には難しいですか? 最初の数日は確かに戸惑いますが、エディタの補完とClaudeCodeの支援を受ければ、むしろJavaScriptより早く慣れます。型エラーは「親切な指摘」と捉えると気持ちが楽になります。
Q2. strictモードを後から有効にするのは大変ですか?
プロジェクトが大きくなるほど大変になります。新規プロジェクトでは最初からstrict: trueで始めることを強くおすすめします。既存プロジェクトの場合は、ファイル単位で// @ts-nocheckを使いつつ徐々に有効化するのが現実的です。
Q3. ts-nodeとtsxはどちらを使えばいい?
2026年現在、tsxが高速で扱いやすいため主流になりつつあります。Node.js 22以降では--experimental-strip-typesで標準対応も始まっていますが、本番運用はまだtsx推奨です。
Q4. anyとunknownの違いは?
anyは何でも代入でき、何でもアクセスできる「型チェックを放棄する型」です。unknownは何でも代入できるが、使う前に型を絞り込む必要がある「安全版any」です。unknownを選びましょう。
Q5. インターフェースとtypeはどちらを使う?
2026年現在はtypeが主流です。柔軟性が高く、ユニオンや交差型を自然に書けます。クラスでimplementsする場合だけinterfaceが便利です。
Q6. Cloudflare Workersで型生成が反映されません。
wrangler typesを実行してから、VSCodeを再起動するかTypeScript Serverを再起動してください。worker-configuration.d.tsがtsconfig.jsonのincludeに含まれているかも確認してください。
Q7. ジェネリクスが難しすぎます。
最初はArray<T>やPromise<T>のような既存のジェネリクスを使うだけで十分です。自分で書くようになるのは数か月後でOK。ClaudeCodeにお手本を作ってもらいながら少しずつ慣れていきましょう。
まとめ
TypeScriptは「型のおかげで安全に・速く・楽に書ける」を実現する強力な言語です。本記事のポイントを振り返ります。strict: trueを必ず有効にし、noUncheckedIndexedAccessなども含めて厳格な設定で出発する。基本型を押さえたら、ユニオン・ジェネリクス・判別可能なユニオンの三点で表現力を伸ばす。anyを排除し、unknown+型ガードで安全に扱う。実行時はzodなどでランタイムバリデーションを併用する。Cloudflare Workers開発ではwrangler typesで型を自動生成し、Hono+D1の組み合わせで型安全なAPIを構築する。これらをClaudeCodeにサポートしてもらえば、TypeScript初心者でも本格的な型安全アプリケーションを作れます。型を味方につけ、バグの少ない開発を実現していきましょう。