typescript-conventions について
TypeScript リポジトリで開発する人向けに、コーディングとレビューの指針を示すスキルです。実行時検証、式の構成、ラッパー、スプレッド、型の形、判断理由の説明を扱います。
主な機能
- 01実行時検証に Valibot を使用
- 02複雑な計算の抽出
- 03単なる中継ラッパーの回避
- 04各スプレッドの目的を明確化
- 05名前付きオブジェクト型をフラットに維持
- 06自明でない判断の説明
活用シーン
- 01TypeScript の実装で規約を適用
- 02保守性を意識した TypeScript 変更のレビュー
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ perdolique/ workflow --skill typescript-conventionsインストール後、Claude Code で/typescript-conventionsを入力して読み込まれたか確認します。
同梱ファイルevals/evals.json
詳細
TypeScript のコーディング規約
- まず、対象ファイルに適用されるリポジトリのドキュメント、AGENTS.md、リントルール、設定を優先してください。このガイダンスは、埋め込み TypeScript を含む TypeScript に適用し、必要に応じて利用可能なフレームワーク、テスト、ライブラリのスキルと組み合わせてください。
- 実行時検証スキーマには Valibot を使用し、プロジェクトのスキーマ構成に従い、該当する場合は既存のコントラクトを再利用してください。
return undefined を避ける
return undefined は使用しないでください。値を返さずに関数を終了する場合は、値を指定しない return を使用してください。
複雑な中間計算を抽出する
- 複雑な計算を引数、プロパティ値、配列要素、条件、ループ入力、スプレッド元、戻り値、またはより大きな式に埋め込む前に、名前付きの
constまたはletに代入してください。 - 通常のネストされた呼び出し、
awaitした値、コンストラクター、連鎖した変換、テンプレートから構築した値、三項演算子、複数の演算子を含む式は、別の計算で使用する前に、意味のある中間変数名を付けてください。 - 例外:プロパティや要素へのアクセス、オプショナルチェーン、
??、単項チェック、単純な比較、1ステップの算術演算など、見ただけで意味が明らかな基本的な式はインラインのままにしてください。このルールに従うことだけを目的に分割しないでください。初期化子に結果を示す意味のある名前が付いている場合は、明快な計算を含めてもかまいません。 - 依存する文は実行順に並べてください。入力を解決し、変換してから、結果を使用してください。
- 宣言型 DSL などの宣言的なライブラリ API では、その構造が宣言を表す場合(スキーマ、クエリ、ルールセットなど)、ネストされた呼び出しや連鎖を維持してください。API で確立されている合成スタイルに従ってください。入力として使う通常のデータ準備は抽出してください。たとえば、
eq(users.id, id)内で使う前に、parseId(rawId)の結果に名前を付けてください。データ変換の連鎖には、通常の抽出ルールを適用してください。 - 動作とアルゴリズムの計算量を維持してください。書式を整えることだけを目的に、中間コレクションや追加の処理を導入しないでください。
意味のない素通しラッパー関数を避ける
- 別の関数を呼び出して結果をそのまま返す、または
awaitして返すことだけが役割の関数は作成しないでください。そのラッパーが実際の概念を表しておらず、検証、分岐、再試行、マッピング、計測、エラー処理などのロジックも担わない場合は、使用箇所に呼び出しをインライン化するか、元の関数の名前を変更してください。 - 明確なドメイン境界を作る場合、または呼び出し元が重複して行うべきでない処理を加える場合に限り、ラッパーを使用してください。
可能な限り、ラッパーのコントラクトはソース側に準拠させる
- 型付き API をラップする場合は、まずソースの型と型推論を再利用してください。ローカルな名前付き型を追加するのは、ラッパーがより限定的なコントラクトを所有する場合、または型チェックによって型推論が不十分だと確認できた場合に限ります。
- ラッパーが戻り値やエラーの形状、ライフサイクル、検証、マッピング、または副作用を変更する場合は、そのコントラクトに名前を付けてテストしてください。
すべてのスプレッドに具体的な理由を求める
- オブジェクトまたは配列の各スプレッドは、選択したフィールドをイミュータブルに変更する、コレクションを結合する、必要な所有境界を作るなど、その構築箇所で具体的な目的を果たさなければなりません。元の値を変更せず、共有しても安全な場合は、浅いコピーを作らずに直接再利用してください。防御的な理由だけで、あるいはコードをイミュータブルに見せるだけのためにスプレッドを使用しないでください。
- ビューモデル、API ペイロード、または意図的に形を整えた別のオブジェクトを作成する場合は、プロパティを明示的に列挙してください。結果のコントラクトを不明瞭にしたり、無関係なフィールドをコピーしたりする広範なソースのスプレッドは使用しないでください。スプレッドは浅い操作です。必要な分離がより深い場合は使用しないでください。
- 実装やレビューでは、各スプレッドの目的を説明できるようにしてください。周囲の処理から目的が明らかでない場合に限り、短いコードコメントを追加してください。本番コード、テスト、フィクスチャにも同じ基準を適用してください。対象を絞ったフィクスチャの上書きには妥当な目的がありますが、不必要なコピーにはありません。
フラットなインターフェース構造を優先する
interface宣言と名前付きオブジェクトtypeエイリアスは、名前付きプロパティを1階層に保ってください。プロパティにオブジェクトの形状が必要な場合は、その形状を独立した名前付きインターフェースとして定義し、親の型から参照してください。- これは、オブジェクトの直接のプロパティ、オブジェクトの配列、
brand: { ... }、items: { ... }[]、brand: { ... } | nullのような nullable 型やユニオン型にも適用してください。 - このルールの対象は型宣言のみです。実行時のオブジェクトリテラル、バリデーターのスキーマ、フレームワークの設定オブジェクト、または再利用可能な型コントラクトではなく実行可能な設定であるライブラリ DSL の値には適用されません。
自明でない判断の理由を説明する
- コードから目的、外部の制約、回避策が明らかでない場合は、短いコメントを追加してください。共有ユーティリティでは、周辺のレイヤーから役割を誤解しやすい場合、そのユーティリティが担う契約を説明してください。
- コードを簡潔にする場合も、その理由は残してください。明白な処理は、行ごとの説明や無関係な実装の詳細ではなく、分かりやすい名前と構造で表現してください。
コメント
Markdown 対応