cases
Builds a predicate/mapper dispatch table, with an optional default.
Lecture
cases builds a matcher out of a list of
(predicate, mapper) pairs: it tries each pair in order, and
the first one whose predicate returns true has its mapper applied to
produce the result. It's a functional stand-in for a chain of
if/else if, and it composes nicely with
map — the returned function is a plain unary
T -> R you can pass straight in.
This shape differs from FxTS on purpose. FxTS's
cases is variadic: each [predicate, mapper] pair
is its own trailing argument, with an optional final bare function acting
as the default, and TypeScript's overloaded generics type each arity by
hand. Dart has neither variadic generics nor per-arity overloads, so
there's no way to accept "any number of pair arguments" and still get
real type checking. FxDart's version instead takes one
List of (predicate, mapper) records
— Dart's tuple type — plus a separate named orElse parameter
so the default is never confused with just another pair.
If nothing matches and no orElse is given, cases
falls back to returning value itself — which only compiles
at the call site if T happens to also satisfy R
— otherwise it throws a StateError at runtime. In practice,
always pass orElse unless you're certain your predicates are
exhaustive.
Demo 1 · Basics
Demo 2 · A grading pipeline
Try it yourself
Exercise: classify each size as 'small' (<10),
'medium' (<30), or 'large'.
when / unless — a single predicate, same result type ·
throwError — a common orElse when no match should be fatal ·
always — a constant orElse ·
matches — a predicate you can plug into a case