| name | structural-constraints |
| description | Guide architecture toward compile-time safety over runtime checks. Use when
designing subsystems, reviewing architecture, or choosing between runtime
and compile-time enforcement. Covers type systems, enums, interfaces.
|
Structural Constraints
Push decisions to compile time. Every runtime check is a bug waiting for the case you forgot.
Checklist
When designing or reviewing:
Patterns
- Enum over string.
Status enum, not status string. The compiler catches typos.
- Constructor validation. Parse, don't validate.
NewEmail(s) returns (Email, error), not string.
- Required fields via types.
Config{Required: X} not Config{Optional: &X}.
- State machines via types.
Draft -> Published -> Archived, not status = "published".
Common Mistakes
- Wrapping everything in interfaces "for testing" — if there's one impl, use the concrete type
- Using
map[string]interface{} when a struct would work — you lose all compile-time checking
- Adding runtime validation for invariants the type system could enforce
- Creating "stringly typed" APIs where enums would prevent invalid states
- Using
interface{} / any to avoid thinking about the actual type
- Feature flags as strings instead of typed constants
- Optional fields that are always present in practice — make them required
- Using error returns for conditions that should be structurally impossible