Narrowing and matching
Inspect Result status, use type guards, and fold both branches into one output.
Discriminant narrowing
if (result.status === "ok") {
result.value;
} else {
result.error;
}
status is the serializable discriminant: "ok" or "error".
Static guards
if (Result.isOk(result)) {
use(result.value);
}
if (Result.isError(result)) {
report(result.error);
}
Instance guards
if (result.isOk()) {
use(result.value);
}
if (result.isErr()) {
report(result.error);
}
isErr() is the instance spelling; Result.isError() is the static spelling.
match
Use match when both branches produce the same output type and you are ready to leave Result:
const statusCode = result.match({
ok: () => 200,
err: (error) => (error._tag === "NotFound" ? 404 : 500),
});
Static data-first and data-last forms are also available:
Result.match(result, {
ok: (value) => value.name,
err: () => "Anonymous",
});
const displayName = Result.match({
ok: (value: User) => value.name,
err: (_error: FindUserError) => "Anonymous",
});
displayName(result);
Match Result first, then tagged errors
const response = result.match({
ok: (user) => ({ status: 200, body: user }),
err: (error) =>
error.match({
UserNotFound: () => ({ status: 404, body: null }),
DatabaseUnavailable: () => ({ status: 503, body: null }),
}),
});
This keeps the two decisions explicit: Result branch first, error variant second.