m05-type-driven
型安全性とコンパイル時の検証を重視し、無効な状態を表現できないように設計することで、より堅牢なコードを構築するタイプ駆動設計を支援するSkill。
📜 元の英語説明(参考)
CRITICAL: Use for type-driven design. Triggers: type state, PhantomData, newtype, marker trait, builder pattern, make invalid states unrepresentable, compile-time validation, sealed trait, ZST, 类型状态, 新类型模式, 类型驱动设计
🇯🇵 日本人クリエイター向け解説
型安全性とコンパイル時の検証を重視し、無効な状態を表現できないように設計することで、より堅牢なコードを構築するタイプ駆動設計を支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o m05-type-driven.zip https://jpskill.com/download/9264.zip && unzip -o m05-type-driven.zip && rm m05-type-driven.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9264.zip -OutFile "$d\m05-type-driven.zip"; Expand-Archive "$d\m05-type-driven.zip" -DestinationPath $d -Force; ri "$d\m05-type-driven.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
m05-type-driven.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
m05-type-drivenフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
型駆動設計
レイヤー 1: 言語のメカニズム
中核となる問い
型システムはどのようにして無効な状態を防ぐことができるか?
ランタイムチェックに手を伸ばす前に:
- コンパイラはこのエラーを捕捉できるか?
- 無効な状態は表現不可能にできるか?
- 型は不変条件をエンコードできるか?
エラー → 設計上の問い
| パターン | 単に言うのではなく | 代わりに問う |
|---|---|---|
| プリミティブへの偏執 | 「ただの文字列だ」 | この値は何を表しているか? |
| ブール値フラグ | 「is_valid フラグを追加する」 | 状態は型になり得るか? |
| どこでもオプショナル | 「None をチェックする」 | 欠如は本当にあり得るか? |
| ランタイムでの検証 | 「無効な場合は Err を返す」 | 構築時に検証できるか? |
思考のプロンプト
ランタイム検証を追加する前に:
-
型は制約をエンコードできるか?
- 数値範囲 → 境界型または newtype
- 有効な状態 → 型状態パターン
- 意味的意味 → newtype
-
いつ検証が可能か?
- 構築時 → 検証済みの newtype
- 状態遷移時 → 型状態
- ランタイムのみ → 明確なエラーを含む Result
-
誰が不変条件を知る必要があるか?
- コンパイラ → 型レベルのエンコーディング
- API ユーザー → 明確な型シグネチャ
- ランタイムのみ → ドキュメント
トレースアップ ↑
型設計が不明確な場合:
"メール形式を検証する必要がある"
↑ 質問: これはドメイン値オブジェクトか?
↑ 確認: m09-domain (Value Object としての Email)
↑ 確認: domain-* (検証要件)
| 状況 | トレース先 | 質問 |
|---|---|---|
| 作成する型 | m09-domain | ドメインモデルは何か? |
| 状態機械の設計 | m09-domain | 有効な遷移は何か? |
| マーカー trait の使用 | m04-zero-cost | 静的ディスパッチか動的ディスパッチか? |
トレースダウン ↓
設計から実装へ:
"プリミティブの型安全なラッパーが必要"
↓ Newtype: struct UserId(u64);
"コンパイル時の状態検証が必要"
↓ Type State: Connection<Connected>
"ファントム型パラメータを追跡する必要がある"
↓ PhantomData: PhantomData<T>
"機能マーカーが必要"
↓ Marker Trait: trait Validated {}
"段階的な構築が必要"
↓ Builder: Builder::new().field(x).build()
クイックリファレンス
| パターン | 目的 | 例 |
|---|---|---|
| Newtype | 型安全性 | struct UserId(u64); |
| Type State | 状態機械 | Connection<Connected> |
| PhantomData | 分散/ライフタイム | PhantomData<&'a T> |
| Marker Trait | 機能フラグ | trait Validated {} |
| Builder | 段階的な構築 | Builder::new().name("x").build() |
| Sealed Trait | 外部実装の防止 | mod private { pub trait Sealed {} } |
パターンの例
Newtype
struct Email(String); // 単なる文字列ではない
impl Email {
pub fn new(s: &str) -> Result<Self, ValidationError> {
// 一度検証したら、永遠に信頼する
validate_email(s)?;
Ok(Self(s.to_string()))
}
}
Type State
struct Connection<State>(TcpStream, PhantomData<State>);
struct Disconnected;
struct Connected;
struct Authenticated;
impl Connection<Disconnected> {
fn connect(self) -> Connection<Connected> { ... }
}
impl Connection<Connected> {
fn authenticate(self) -> Connection<Authenticated> { ... }
}
意思決定ガイド
| ニーズ | パターン |
|---|---|
| プリミティブの型安全性 | Newtype |
| コンパイル時の状態検証 | Type State |
| ライフタイム/分散マーカー | PhantomData |
| 機能フラグ | Marker Trait |
| 段階的な構築 | Builder |
| 実装のクローズドセット | Sealed Trait |
| ゼロサイズの型マーカー | ZST struct |
アンチパターン
| アンチパターン | なぜ悪いか | より良い方法 |
|---|---|---|
| 状態のためのブール値フラグ | ランタイムエラー | Type state |
| 意味的型のための String | 型安全性がない | Newtype |
| 未初期化のための Option | 不明瞭な不変条件 | Builder |
| 不変条件を持つパブリックフィールド | 不変条件の違反 | Private + 検証済みの new() |
関連スキル
| いつ | 参照 |
|---|---|
| ドメインモデリング | m09-domain |
| Trait 設計 | m04-zero-cost |
| コンストラクタでのエラー処理 | m06-error-handling |
| アンチパターン | m15-anti-pattern |
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Type-Driven Design
Layer 1: Language Mechanics
Core Question
How can the type system prevent invalid states?
Before reaching for runtime checks:
- Can the compiler catch this error?
- Can invalid states be unrepresentable?
- Can the type encode the invariant?
Error → Design Question
| Pattern | Don't Just Say | Ask Instead |
|---|---|---|
| Primitive obsession | "It's just a string" | What does this value represent? |
| Boolean flags | "Add an is_valid flag" | Can states be types? |
| Optional everywhere | "Check for None" | Is absence really possible? |
| Validation at runtime | "Return Err if invalid" | Can we validate at construction? |
Thinking Prompt
Before adding runtime validation:
-
Can the type encode the constraint?
- Numeric range → bounded types or newtypes
- Valid states → type state pattern
- Semantic meaning → newtype
-
When is validation possible?
- At construction → validated newtype
- At state transition → type state
- Only at runtime → Result with clear error
-
Who needs to know the invariant?
- Compiler → type-level encoding
- API users → clear type signatures
- Runtime only → documentation
Trace Up ↑
When type design is unclear:
"Need to validate email format"
↑ Ask: Is this a domain value object?
↑ Check: m09-domain (Email as Value Object)
↑ Check: domain-* (validation requirements)
| Situation | Trace To | Question |
|---|---|---|
| What types to create | m09-domain | What's the domain model? |
| State machine design | m09-domain | What are valid transitions? |
| Marker trait usage | m04-zero-cost | Static or dynamic dispatch? |
Trace Down ↓
From design to implementation:
"Need type-safe wrapper for primitives"
↓ Newtype: struct UserId(u64);
"Need compile-time state validation"
↓ Type State: Connection<Connected>
"Need to track phantom type parameters"
↓ PhantomData: PhantomData<T>
"Need capability markers"
↓ Marker Trait: trait Validated {}
"Need gradual construction"
↓ Builder: Builder::new().field(x).build()
Quick Reference
| Pattern | Purpose | Example |
|---|---|---|
| Newtype | Type safety | struct UserId(u64); |
| Type State | State machine | Connection<Connected> |
| PhantomData | Variance/lifetime | PhantomData<&'a T> |
| Marker Trait | Capability flag | trait Validated {} |
| Builder | Gradual construction | Builder::new().name("x").build() |
| Sealed Trait | Prevent external impl | mod private { pub trait Sealed {} } |
Pattern Examples
Newtype
struct Email(String); // Not just any string
impl Email {
pub fn new(s: &str) -> Result<Self, ValidationError> {
// Validate once, trust forever
validate_email(s)?;
Ok(Self(s.to_string()))
}
}
Type State
struct Connection<State>(TcpStream, PhantomData<State>);
struct Disconnected;
struct Connected;
struct Authenticated;
impl Connection<Disconnected> {
fn connect(self) -> Connection<Connected> { ... }
}
impl Connection<Connected> {
fn authenticate(self) -> Connection<Authenticated> { ... }
}
Decision Guide
| Need | Pattern |
|---|---|
| Type safety for primitives | Newtype |
| Compile-time state validation | Type State |
| Lifetime/variance markers | PhantomData |
| Capability flags | Marker Trait |
| Gradual construction | Builder |
| Closed set of impls | Sealed Trait |
| Zero-sized type marker | ZST struct |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Boolean flags for states | Runtime errors | Type state |
| String for semantic types | No type safety | Newtype |
| Option for uninitialized | Unclear invariant | Builder |
| Public fields with invariants | Invariant violation | Private + validated new() |
Related Skills
| When | See |
|---|---|
| Domain modeling | m09-domain |
| Trait design | m04-zero-cost |
| Error handling in constructors | m06-error-handling |
| Anti-patterns | m15-anti-pattern |