♻️ Share matcher internals

This commit is contained in:
tmu committed 2026-09-21 23:15:09 +00:00
1 parent 6f4f509b69
commit 937d84ea48
4 files changed
+63 -26

No files matched your search

+7 -13
View File
@@ -1,6 +1,11 @@
import type { Exact, UnknownRecord, ValueOf } from "type-fest";
import type { Exact, UnknownRecord } from "type-fest";
type UnaryFn<T, R> = (shape: T) => R;
import type {
HandlerMap,
PatternReturns,
RedundantFallback,
UnaryFn,
} from "./matcher-shared.ts";
// A tagged union is discriminated by one property whose values are the tags.
// Only `string` and `number` tags can key a handler map: `symbol` has no
@@ -28,12 +33,6 @@ type Handlers<T extends object, K extends keyof T, R> = {
[V in Tags<T, K>]: UnaryFn<MapTaggedUnion<T, K>[V], R>;
};
// `Extract` drops optional handlers (`undefined`) so `PatternReturns` also works
// when `P`'s constraint has optional keys.
type PatternReturns<P> = ReturnType<
Extract<ValueOf<P>, (...args: never[]) => unknown>
>;
// The members `Handled` covers. Mapping over `Tags` keeps every index within
// `MapTaggedUnion`'s keys, and the conditional drops a stray key outside `T` so
// it cannot widen the remainder. The remainder is `Exclude<T, …>`, mirroring
@@ -55,9 +54,6 @@ type Fallback<T extends object, K extends keyof T, Handled, R> = UnaryFn<
// into `Handled`'s own (self-referential) constraint so it is checked *after*
// inference; see the primitive matcher for why a conditional in the fallback's
// parameter is evaluated too early.
interface RedundantFallback {
readonly "every case is already handled, so the fallback is redundant": never;
}
type MustBePartial<T extends object, K extends keyof T, Handled> =
Tags<T, K> extends keyof Handled ? RedundantFallback : unknown;
@@ -96,8 +92,6 @@ interface TaggedUnionMatcherWidening<T extends object, K extends keyof T> {
): UnaryFn<T, PatternReturns<Handled> | R>;
}
type HandlerMap = Record<string | number, UnaryFn<never, unknown> | undefined>;
const dispatch =
(k: PropertyKey) =>
(handlers: HandlerMap, fallback?: UnaryFn<never, unknown>) =>