import type { Fn } from "../types/fn.ts"; import { type TaggedVariant, type VariantFromTag, VariantTag, } from "./variant.ts"; export type VariantMatcher, T> = { [K in TVariant[VariantTag]]: Fn, T>; }; export function match>( v: TVariant, ) { return { case< const TReturnType, const TMatcher extends VariantMatcher< TVariant, TReturnType > = VariantMatcher, >(cases: TMatcher): TReturnType { if (!(v[VariantTag] in cases)) { throw new Error("Non-exhaustive pattern match"); } return cases[v[VariantTag] as TVariant[VariantTag]]( v as Extract, ); }, }; }