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, 类型状态, 新类型模式, 类型驱动设计
View on GitHubactionbook/rust-skills
rust-skills
January 23, 2026
Select agents to install to:
npx add-skill https://github.com/actionbook/rust-skills/blob/main/skills/m05-type-driven/SKILL.md -a claude-code --skill m05-type-drivenInstallation paths:
.claude/skills/m05-type-driven/# 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:
1. **Can the type encode the constraint?**
- Numeric range → bounded types or newtypes
- Valid states → type state pattern
- Semantic meaning → newtype
2. **When is validation possible?**
- At construction → validated newtype
- At state transition → type state
- Only at runtime → Result with clear error
3. **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"