principle-type-system-discipline

Applies type system patterns to make illegal states unrepresentable in statically-typed code.

3|2|Updated Aug 28, 2026
One-click install
npx skills add https://github.com/adjohn/pstack --skill principle-type-system-discipline-adjohn
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: principle-type-system-discipline
Source: https://github.com/adjohn/pstack/tree/main/skills/principle-type-system-discipline
Command: npx skills add https://github.com/adjohn/pstack --skill principle-type-system-discipline-adjohn

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Codebases accumulate runtime failures that the compiler could have prevented: contradictory optional fields, interchangeable primitive IDs, unchecked casts, and non-exhaustive matches. This Skill provides a set of type design principles that push these errors from runtime to compile time. ## Core Features & Use Cases - Illegal State Elimination: Model variants as sum types (discriminated unions, enums with payloads, sealed classes) instead of bags of optional fields. - Boundary Validation: Parse external data (JSON, RPC payloads, env vars, database rows) into typed models at every boundary, and brand semantic primitives like UserId versus OrderId. - Exhaustiveness and Totality: Enforce compiler-checked exhaustive matching and prefer total functions over partial ones with runtime assertions. - Use Case: When reviewing a TypeScript function signature like { completed: boolean; completedAt?: Date }, apply the Skill to remodel it as { kind: 'open' } | { kind: 'done'; at: Date } so contradictory states cannot compile. ## Quick Start Ask the AI to review this function signature and apply type system discipline to make illegal states unrepresentable.

Frequently Asked Questions about principle-type-system-discipline

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I make illegal states unrepresentable in TypeScript?

Model variants as discriminated unions instead of optional field bags. For example, replace `{ completed: boolean; completedAt?: Date }` with `{ kind: 'open' } | { kind: 'done'; at: Date }` so contradictory combinations cannot compile.

How to prevent mixing up primitive types like UserId and OrderId?

Brand semantic primitives so they are not interchangeable: use branded intersections in TypeScript, newtypes in Rust, opaque types in Swift, or value classes in Kotlin. Validate once at creation, then trust the type downstream.

Does this approach work in languages other than TypeScript?

Yes, the principles apply to any statically-typed language. It covers enums with payloads in Rust, Swift, and Kotlin, sealed classes in Scala, and ADTs in Haskell and OCaml, with language-specific idioms for each pattern.

When should I avoid strengthening a type further?

Strengthen a type only where partiality actually appears, such as a runtime assertion or null check. Extra precision beyond what keeps operations total costs reuse and ceremony without buying additional safety.

Why are type casts and assertions considered hazardous?

Casts and assertion functions bypass the compiler's proof, turning checkable facts into runtime crashes. Instead, validate and narrow at the boundary where untyped data enters, or refine the model so the compiler can prove the fact.