principle-type-system-discipline について
不可能な状態、意味の異なる基本型の混同、未処理のバリアントをコンパイラーで検出するための、言語横断の型システムスキルです。構成的なモデリング、境界での解析、網羅性チェックを指針として示します。
主な機能
- 01不正な状態を表現不能にする
- 02有効値から型を構成する
- 03意味を持つ基本型のブランド化
- 04境界での未型付けデータの解析
- 05網羅的なパターンマッチの要求
- 06権威あるスキーマから型を導出
活用シーン
- 01矛盾するフィールドのないバリアント設計
- 02意味の異なる ID の分離
- 03アプリケーションに入るデータの検証
- 04新しいバリアントのコンパイル時処理の徹底
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mdsmithaustin/ pstack --skill principle-type-system-disciplineインストール後、Claude Code で/principle-type-system-disciplineを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
型システムの規律
コンパイラーに、不可能な状態、プリミティブ型の不一致、未処理のバリアントを拒否させましょう。ハンドラーを増やすより、エラーや特殊ケースそのものをなくすことを優先してください。TypeScript の構文については、typescript-best-practices スキルを参照してください。
- 不正な状態を表現できないようにします。 バリアントは、矛盾する組み合わせでもコンパイルできてしまう任意フィールドの寄せ集めではなく、直和型(判別可能ユニオン、ペイロード付き列挙型、シールドクラス)としてモデル化します。
{ completed: boolean; completedAt?: Date }では、completed: trueなのに日付がない状態が許されます。completedAtから真偽値を導出するか、{ kind: 'open' } | { kind: 'done'; at: Date }のようにモデル化してください。フィールドの組み合わせが有効となる条件を説明するコメントを書けるなら、直和型に分割してください。 - 型は制約ではなく、構成するものです。 より緩い型をチェックで削り出すのではなく、必要な値から型を組み立てます。空でないリストは、先頭要素と残りの要素で構成されます。有効な時間範囲は、開始時刻と継続時間で構成されます。不正な値を構築できない形を選び、その上に呼び出し側が必要とするインターフェースを公開してください。
- 意味を持つプリミティブ型にはブランドを付けます。
UserIdとOrderIdは内部的にはどちらも文字列ですが、相互に置き換えられるべきではありません。それぞれに、TypeScript のブランド付き交差型や他の言語の新しい型など、独自の型を与えてください。作成時に一度検証したら、その後は型を信頼します。プリミティブ型が同じでも意味が異なる引数には、ブランドを付けてください。 - 解析するまでは、外部データに型があると見なしてはいけません。 RPC ペイロード、JSON、IPC メッセージ、CLI 引数、設定ファイル、環境変数、データベースの行などが該当します。各境界に、構造化されていない入力を型付きモデルに変換する解析関数を用意します。検証をどこに置くかについては、principle-boundary-discipline スキルを参照してください。
- 型システムを欺いてはいけません。 キャスト、安全でない型強制、コンパイラーを迂回するアサーション関数は、潜在的な実行時クラッシュの原因です。コンパイラーが事実を証明できないなら、その事実を証明する(検証する、型を絞り込む、モデルを洗練する)か、キャストが危険であることを受け入れてください。各
any、as、assertNotNullを境界までたどり、そこで検証してください。 - 網羅的なパターンマッチングはコンパイラーに任せます。 直和型へのマッチは、新しいバリアントが追加されたときに未処理のままだとコンパイルに失敗し、次のエージェントにケースを追加すべき場所をコンパイラーが知らせるようにします。各言語の慣用的な方法を使ってください。TypeScript では
never型の変数束縛、Rust では注釈なしのmatch、Haskell では-Wincomplete-patterns、Kotlin ではシールドクラスの網羅性チェック付きマッチを使います。 - 信頼できるスキーマから型を導出します。 Protocol Buffers、OpenAPI 仕様、GraphQL スキーマ、データベースマイグレーション、デザイントークンファイルなど、形状を定めるファイルがある場合は、並行する型を手作業で作らず、そこから型を導出します。
principle-encode-lessons-in-structureを指定して Skill ツールを呼び出してください。 - 部分性が現れる箇所だけで型を強化します。 実行時アサーション、null チェック、「これは決して起きないはず」という例外は、型が弱すぎる場所を示しています。そのチェックを型に押し上げてください。そのうえで止めます。型システムの役割は、各利用箇所が処理すべきケースを追跡することであり、データを可能な限り正確に記述することではありません。全域関数を優先してください。空のリストの
sumは 0 なので、通常のリストを受け取ります。空のリストのheadには答えがないので、空でないリストを要求します。ほかにパニックが起きないなら、通常の型のままにしてください。
コメント
Markdown 対応