♻️ Name the matcher factories getMatcher / getMatcherW

Drop the strict/widened aliases from src/index.ts so the factories are
exported under their own names, and align the type tests, the autocomplete
probe (which now imports the public surface from ./index.ts) and library.md
with them.

Also correct the widened-overload comment: the excess-property check does not
apply to a generic P, so MatcherWidening's keyof guard — not the closed
constraint — is what rejects keys outside T/_, as library.md already
documented.
This commit is contained in:
tmu committed 2026-09-17 21:48:54 +00:00
1 parent 05fad0fcd6
commit 800c11139d
5 files changed
+69 -84

No files matched your search

+8 -7
View File
@@ -4,7 +4,8 @@ The type-level design of the public API and the limitations it carries. The
user-facing reference is [README § API](../README.md#api).
The matcher below is implemented in `src/primitive.ts` and re-exported from
`src/index.ts`; the rest of the library is placeholder code.
`src/index.ts` as `getMatcher` / `getMatcherW`; the rest of the library is
placeholder code.
## Matcher shape
@@ -13,15 +14,15 @@ The matcher below is implemented in `src/primitive.ts` and re-exported from
A matcher is built by a factory and applied to a pattern:
```ts
const matcher = strict<"a" | "b">()({ a: (s) => …, b: (s) => … });
const matcher = getMatcher<"a" | "b">()({ a: (s) => …, b: (s) => … });
```
Whether the pattern is exhaustive or has a fallback is decided **at the call
site**, by whether it carries `_` — F#'s `| _ ->`. Only the return-strictness
axis remains, so there are two factories:
- `strict` — one common `R`, the best common return type of every handler;
- `widened` — the union of every handler's return type.
- `getMatcher` — one common `R`, the best common return type of every handler;
- `getMatcherW` — the union of every handler's return type.
Both are three overloads whose order is load-bearing:
@@ -43,9 +44,9 @@ Both are three overloads whose order is load-bearing:
#### Rejected
- **Four factories** (`src/primitive.ts` today: exhaustive × fallback ×
strict/widened). The exhaustive/fallback axis is expressible as one pattern
type; four signatures duplicate it.
- **Four factories** (exhaustive and fallback each split by return handling).
The exhaustive/fallback axis is expressible as one pattern type; four
signatures duplicate it.
- **Union merge** — one type `Exhaustive<R,T> | (Partial<…> & { _: … })`,
explicit `<T>()`. Type-safe and completable, but TypeScript reports the
near-miss union member, so a missing key reads `Property '_' is missing`