import type { AnyTaggedError } from "./error.ts" export type MatchTaggedErrorHandlers = { [Tag in E["tag"]]: (error: Extract) => R } export const matchTaggedError = ( taggedError: E, handlers: MatchTaggedErrorHandlers, ): R => { const handler = handlers[taggedError.tag as E["tag"]] if (handler === undefined) { throw new Error(`No handler for tag: ${taggedError.tag}`) } return handler(taggedError as Extract) } export type MatchTaggedErrorPartialHandlers = { [Tag in E["tag"]]?: ((error: Extract) => R) | undefined } type UnhandledTaggedError = Exclude export const matchTaggedErrorPartial = < E extends AnyTaggedError, R, const Handlers extends MatchTaggedErrorPartialHandlers = MatchTaggedErrorPartialHandlers< E, R >, >( taggedError: E, handlers: Handlers, fallback: (error: UnhandledTaggedError) => R, ): R => { const handler = handlers[taggedError.tag as E["tag"]] if (handler !== undefined) { return handler(taggedError as Extract) } return fallback(taggedError as UnhandledTaggedError) }