typescript-react-nextjs-patterns について
TypeScript、React、Next.js を扱う AI コーディングエージェント向けの体系的なリファレンススキルです。バージョンを考慮したパターン、判断ガイド、コード生成チェックリスト、デバッグとレビュー資料を備えています。
主な機能
- 01TypeScript と React のパターン集
- 02Next.js のバージョン別ガイダンス
- 03ランタイム検証の判断ガイド
- 04コード生成チェックリスト
- 05デバッグとレビューの資料
活用シーン
- 01React コンポーネントの実装をガイド
- 02Next.js のルーティングと境界パターンを確認
- 03型安全性のリスクをコードレビュー
- 04ハイドレーションや Effect の問題を診断
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ leejpsd/ typescript-react-nextjs-patterns --skill typescript-react-nextjs-patternsインストール後、Claude Code で/typescript-react-nextjs-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEHARD-RULES.mdREADME.mdREADME.ko.mdplaybooks/type-error-debugging.mdeffect-dependency-bugs.mdhydration-issues.mdrules/code-review-rules.mdanti-patterns.mdforms-and-validation.mddebugging-checklists.mdcomponent-patterns.mdstate-management.mdnextjs-typescript.mddata-fetching-and-api-types.mdtypescript-core.mdreact-typescript-patterns.mdperformance-and-accessibility.md詳細
React & Next.js 向け TypeScript — エージェントスキル
本番環境で TypeScript、React、Next.js を使用するフロントエンドエンジニアを支援する AI コーディングエージェント向けの、体系的なリファレンスです。
エージェントの動作ルール
回答する前に、必ず確認してください。
- サーバー側ですか、クライアント側ですか? Server Components、Server Actions、Route Handlers には、
"use client"コンポーネントとは異なる型の制約があります。 - ランタイム検証が必要ですか? 静的型は、API レスポンス、URL パラメーター、フォームデータ、localStorage を検証しません。信頼境界を越えるデータには、Zod または同等のものが必要です。
- App Router と Pages Router のどちらですか? パターンは大きく異なります。不明な場合は質問してください。
- TypeScript のバージョンは何ですか?
satisfiesには 5.0 以降、NoInferには 5.4 以降、推論される型述語には 5.5 以降が必要です。TS 6.0 は JavaScript ベースのコンパイラーとしては最後のバージョンです。TS 7 は Go ネイティブへの書き換え版で、同じ言語のまま約 10 倍高速ですが、古いコンパイラー API を利用するツールは対応が遅れる可能性があります。 - Next.js のバージョンは何ですか? 15 以降では
paramsはPromiseです。16 以降ではキャッシュモデルが変更され("use cache")、16 ではmiddleware.tsがproxy.tsに改名されます(Node ランタイム)。 - React のバージョンは何ですか? 19 では
refが通常のプロパティになり(forwardRefは非推奨)、<Context>を直接レンダーできるようになり、useFormStateはuseActionStateに置き換えられます。useEffectEventと<Activity>には 19.2 以降が必要です。
エージェントが想定してはならないこと:
- 実行時に API レスポンスが TypeScript の型と一致すること
searchParamsの値が想定した型であること(常にstring | string[] | undefinedです)- 既存コードの
anyが意図的に使われていること - コンテキストを確認せずに型アサーション(
as)が正当化されること - クライアントコンポーネントでサーバー専用のインポートを安全に使えること
- 既存コードの
useEffectの依存配列が正しいこと
不確かな場合:
- どれかのアプローチを黙って選ぶのではなく、トレードオフを明示してください
- 不安定なパターンやバージョンに依存するパターンには、その旨を記してください
- 次のように区別してください:[HARD RULE](違反するとバグが発生)/[DEFAULT](理由があれば変更可)/[SITUATIONAL](状況による)
コンテキスト圧縮後:
このセッションが圧縮され、ルールの内容が要約としてのみ残っている場合:
- 要約を基に回答してはいけません。要約では、理由、例、エッジケースが失われています。
- 続行する前に、以下の Decision Guide から関連ファイルを読み直してください。ここは意図的に簡潔にしてあるため、ファイルを 1 つ読むだけで十分です。
- 作業の途中で、どのファイルが該当するか不明な場合は、まず
HARD-RULES.mdを読み直してください。圧縮された形で、すべての必須ルールが記載されています。
Decision Guide
クイックガイド:どのパターンを使うべきですか?
| 状況 | まず読むもの |
|---|---|
| コンポーネントの Props、children、イベント、ref の型付け | → react-typescript-patterns.md |
Union の絞り込み、unknown、型ガード、ユーティリティ型 | → typescript-core.md |
| Next.js の params、searchParams、Server Actions、RSC の境界 | → nextjs-typescript.md |
| 判別可能な Union、条件付き Props、複合コンポーネント | → component-patterns.md |
| API レスポンス、fetch の型付け、TanStack Query、キャッシュ | → data-fetching-and-api-types.md |
| フォームの状態、検証、制御コンポーネントと非制御コンポーネント | → forms-and-validation.md |
| ローカル状態、コンテキスト、サーバー状態、Zustand の使い分け | → state-management.md |
| 再レンダー、メモ化、アクセシビリティ | → performance-and-accessibility.md |
| 型エラー、ハイドレーション、古い状態、エフェクトのバグ | → debugging-checklists.md(ハブ)+ playbooks/ |
| PR レビュー、リスクと好み、アーキテクチャ上の問題 | → code-review-rules.md |
| よくある間違い、カーゴカルト的なパターン | → anti-patterns.md |
フローチャート:このデータは安全に使用できますか?
Data comes from...
├─ Inside the app (useState, useReducer, computed)
│ → Static typing is sufficient. No runtime validation needed.
│
├─ Outside the app (API, URL, FormData, localStorage, postMessage)
│ → [HARD RULE] Validate at runtime. Use Zod or equivalent.
│ │
│ ├─ API response → schema.parse(await res.json())
│ ├─ URL params → schema.parse(searchParams)
│ ├─ FormData → schema.safeParse({ field: formData.get('field') })
│ ├─ localStorage → schema.safeParse(JSON.parse(stored))
│ └─ postMessage → schema.safeParse(event.data)
│
└─ Third-party library callback
→ Check library types. Add runtime guard if types seem wrong.
フローチャート:この状態はどこに置くべきですか?
Is this data from a server/API?
├─ Yes → TanStack Query (NOT useState). See data-fetching-and-api-types.md
│
└─ No → Is it shareable via URL? (filters, page, sort)
├─ Yes → searchParams or nuqs. See state-management.md
│
└─ No → How many components need it?
├─ 1 component → useState or useReducer
├─ 2-3 in same tree → Lift state up (props)
└─ Many across trees → How often does it change?
├─ Rarely (theme, locale, auth) → Context
└─ Often (cart, notifications) → Zustand with selectors
フローチャート:これをメモ化すべきですか?
Is there a measured performance problem?
├─ No → Don't memoize. Stop here.
│
└─ Yes → Can you restructure instead?
├─ Yes → Move state down, extract components. See performance-and-accessibility.md
│
└─ No → What needs memoizing?
├─ Expensive computation → useMemo (verify it's truly expensive)
├─ Callback to memoized child → useCallback
└─ Component in a long list → React.memo (verify props are stable)
クイックリファレンス:必須ルール、デフォルト、状況次第
| ラベル | 意味 | 例 |
|---|---|---|
| [HARD RULE] | 違反するとバグやセキュリティ上の問題が発生します。例外はありません。 | 「API レスポンスを実行時に検証する」 |
| [DEFAULT] | 逸脱する理由を文書化していない限り、推奨される選択肢です。 | 「Props には interface を使う」 |
| [SITUATIONAL] | 状況によって異なります。どちらの選択肢も有効です。選択理由を説明してください。 | 「ポリモーフィックコンポーネント — デザインシステムの基盤に限る」 |
[DEFAULT] から逸脱する場合は、後のセッションでも理由がわかるように、逸脱箇所の一行コメントまたはコミットメッセージに理由を書いてください。コンテキストの圧縮や新しいセッションでは、その理由を思い出せないためです。
コード生成チェックリスト
TypeScript/React/Next.js のコードを生成する前に、以下を確認してください。
コンテキスト
- 確認済み:サーバー側のコードか、クライアント側のコードか?
- 確認済み:App Router か、Pages Router か?
- 確認済み:TypeScript の strict モードが有効か?
型安全性
-
anyを使わない — 検証を伴うunknownまたは適切な型を使う - 文書化された正当な理由がない限り
asを使わない - 外部データ(API、URL、フォーム、ストレージ)を実行時に検証する
- Props には
interfaceを使い、本当に省略可能なフィールドに限って?を付ける
React
-
childrenの型をReact.ReactNodeにする - イベントハンドラーの Props ではイベントオブジェクトではなく値を公開する
- Effect に安定した依存関係とクリーンアップ関数を設定する
-
"use client"は必要な場所だけに、可能な限り深い階層で使う - サーバーデータを
useStateに重複して保持しない
Next.js(15+)
-
paramsとsearchParamsを await する - Server Actions では Zod を使って FormData を検証する
-
import 'server-only'で機密性の高いコードを保護する - 境界をまたぐ Props が RSC でシリアライズ可能である(通常のコールバックやクラスインスタンスは不可。
Date/Map/Set/Promiseは使用可能)
アクセシビリティ
- フォーム入力に対応するラベルを設定する
- エラーメッセージに
role="alert"を使用する - インタラクティブな要素をキーボードで操作できるようにする
コードレビューのチェックリスト
リスクとして指摘する(バグや保守上の問題の可能性が高い)
- 理由が文書化されていない
any - 検証されていない外部データへの
as - 事前のガードなしで使われる
!による非 null アサーション - オブジェクト/配列を依存関係に持つ
useEffect(不安定な可能性が高い) useEffectのクリーンアップ漏れ- サーバーデータを
useStateにコピーしている - ページ/レイアウトレベルの
"use client" - Server Function 以外のコールバックまたはクラスインスタンスを、サーバー/クライアント境界をまたいで渡している
params/searchParamsを await していない(Next.js 15+)- FormData の検証を行っていない Server Action
好みとして指摘する(言及するが、ブロックはしない)
- オブジェクトの形状に対する
typeとinterfaceの使い分け - ハンドラーの命名規則
- ファイル/フォルダーの整理方法
- インポートの順序
ファイル一覧
| ファイル | 内容 |
|---|---|
HARD-RULES.md | すべての[厳守ルール]を1ページに集約 — 圧縮後の復元、CLAUDE.mdへの埋め込み、フックによる注入 |
typescript-core.md | 型の絞り込み、ユニオン、ジェネリクス、ユーティリティ型、型推論、unknown と any の違い、as const、satisfies |
react-typescript-patterns.md | Props、children、イベント、ref(refをpropとして扱う19、forwardRefを使う18)、フック、コンテキスト |
nextjs-typescript.md | App Routerの型、params、searchParams、Server Actions、RSCの境界、Cache Components(16)、proxy.ts、メタデータ |
component-patterns.md | 判別可能なユニオン型のProps、複合コンポーネント、制御コンポーネント/非制御コンポーネント、多相 |
data-fetching-and-api-types.md | Fetchの型付け、Zodによるバリデーション、TanStack Query、安全なレスポンス処理 |
forms-and-validation.md | フォームの状態、Zod、react-hook-form、Server Actions、段階的な機能強化 |
state-management.md | ローカル状態、Context、Zustand、TanStack Query、URLの状態、選択マトリクス |
performance-and-accessibility.md | メモ化のトレードオフ、エフェクトの安定性、セマンティックHTML、ARIAのパターン |
debugging-checklists.md | 迅速な診断フロー、シリアライズの問題、nullへのアクセス、再レンダリングのエラー |
code-review-rules.md | リスクと好みの違い、アーキテクチャ上の問題の兆候、レビューコメントのテンプレート |
anti-patterns.md | よくある13の間違いと、その根本原因および修正方法 |
playbooks/ — 手順に沿ったデバッグガイド(特定のバグの診断時に参照)
| ファイル | 内容 |
|---|---|
type-error-debugging.md | React/Next.js固有のエラーを含む、体系的な型エラーの解決方法 |
hydration-issues.md | SSR/CSRの不一致を診断するフローチャートと修正パターン |
effect-dependency-bugs.md | 無限ループ、古いクロージャ、クリーンアップの欠落、実例に基づくデバウンスの例 |
コメント
Markdown 対応