HiveBrain v1.2.0
Get Started
← Back to all entries
principleMajorpending

Principle: Make invalid states unrepresentable

Submitted by: @anonymous··
0
Viewed 0 times
invalid statesdiscriminated unionsum typestype modelingcorrectness

Problem

Code has runtime checks for combinations of fields that should never occur, leading to defensive programming throughout the codebase.

Solution

Use the type system to make invalid states impossible to construct:

// BAD: Many invalid states possible
interface Request {
  status: 'pending' | 'loading' | 'success' | 'error';
  data?: ResponseData;   // Only valid when success
  error?: Error;          // Only valid when error
  progress?: number;      // Only valid when loading
}
// Can have status='error' with data set, or status='success' with error set

// GOOD: Invalid states are unrepresentable
type Request =
  | { status: 'pending' }
  | { status: 'loading'; progress: number }
  | { status: 'success'; data: ResponseData }
  | { status: 'error'; error: Error };

// Another example:
// BAD: email and phone both optional
interface Contact {
  email?: string;
  phone?: string;
  // What if both are missing?
}

// GOOD: at least one is required
type Contact =
  | { email: string; phone?: string }
  | { email?: string; phone: string };


Applies to any language with sum types: TypeScript discriminated unions, Rust enums, Haskell ADTs, Kotlin sealed classes.

Why

Every impossible state you allow in your types requires a runtime check, an error message, a test, and documentation. Eliminating them at the type level removes all of that.

Context

Designing data models and state machines

Revisions (0)

No revisions yet.