♻️ Share matcher internals
This commit is contained in:
1 parent
6f4f509b69
commit
937d84ea48
4 files changed
+63
-26
No files matched your search
+7
-13
@@ -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>) =>
|
||||
|
||||
Reference in new issue
Block a user