Finite State Machines for Complex UI Logic in TypeScript

Boolean flags are a tax. Every new edge case adds another isLoading, hasError, isRetrying, wasSubmitted — and soon you're maintaining a dozen booleans that can combine into states that should never exist. A form that's simultaneously isLoading and hasError from a previous attempt. A button that's disabled for three different reasons, none of them explicit. Finite state machines (FSMs) eliminate this entire class of bug at the type level.

Here's a typical async form component. It's familiar because we've all written it.