Using Standalone Functions
When to use the standalone style, how value-first APIs work, and how they compose with TypeScript inference.
The standalone functions are dismatch's value-first surface. Each one takes
the value (or collection) first, the discriminant key (optional, defaults to
"type"), and returns a function that accepts your handlers.
import { match } from "dismatch";
const area = match(shape)({
circle: ({ radius }) => Math.PI * radius ** 2,
rectangle: ({ width, height }) => width * height,
});That two-step shape — (value, discriminant?) => (handlers) => result — is
the convention every standalone function follows. Once you internalise it,
the rest of the API becomes a vocabulary on top of the same core idea.
When to reach for the standalone style
Use standalone functions when you have already-typed unions and don't need a single factory to manage them:
- A union declared as a plain
typeyou didn't author. - A value coming from
JSON.parseafter a runtime check. - A reducer's
Actiontype defined with raw object literals. - A sibling library's exported union.
If you control the shape and want one schema to drive constructors, type
guards, and matching — use createUnion instead.
If you have a typed union and want to bind handlers once and reuse them
across many call sites or inside a pipe, use
createPipeHandlers.
Custom discriminant
Every standalone function accepts an optional discriminant key. The default
is "type", so you can usually omit it:
match(shape)({ circle: ..., rectangle: ... }); // type
match(event, "kind")({ click: ..., key: ... }); // kind
is(event, "click", "kind");
isUnion(event, "kind");See Custom discriminant for the factory equivalent.
Sync vs async
Async lives at dismatch/async:
import { matchAsync } from "dismatch/async";
const profile = await matchAsync(user)({
admin: async ({ id }) => fetchAdminProfile(id),
guest: async ({ id }) => fetchGuestProfile(id),
});Mixing sync and async handlers is fine — the result still unifies to
Promise<R>, never Promise<A> | Promise<B>. See the Async
APIs page for the full surface and the motivation.
Where next
The Standalone API section covers each function with examples:
- Matching —
match,matchWithDefault - Mapping —
map,mapAll - Folding —
fold,foldWithDefault - Predicates & Stats —
is,count,partition,isUnion - Errors —
UnknownVariantError