♻️ Keep the public API to the four factories

The builder types are already the inferred return types and travel into
the emitted .d.ts, so exporting them only made them nameable while
pinning the internal Strict/Widening split as API. Revert the type
exports and the public renames, drop the type-surface test, and document
only the factories in README and development/library.md.
This commit is contained in:
tmu committed 2026-09-23 22:19:02 +00:00
1 parent 9c9468fa3c
commit 5ddbbdc183
7 files changed
+37 -145

No files matched your search

-49
View File
@@ -8,18 +8,8 @@ import {
getPrimitiveUnionMatcherW,
getTaggedUnionMatcher,
getTaggedUnionMatcherW,
type PrimitiveUnionMatcher,
type PrimitiveUnionMatcherW,
type TaggedUnionMatcher,
type TaggedUnionMatcherFactory,
type TaggedUnionMatcherW,
type TaggedUnionMatcherWFactory,
} from "./index.ts";
interface Shape {
readonly kind: "circle" | "square";
}
// The published entry point is the barrel (`package.json` exports
// `./dist/index.js`), so every factory must be reachable from here. Importing it
// also loads the module, which is what lets c8's `--all` measure it — see
@@ -35,42 +25,3 @@ test("index: the public entry point re-exports every matcher factory", () => {
expectTypeOf(getTaggedUnionMatcherW).toBeFunction();
assert.equal(typeof getTaggedUnionMatcherW, "function");
});
// The builder types are part of the public contract: a consumer annotates a
// factory result with them, so the exported names must match the inferred
// return types.
test("index: the primitive-union factories return the exported builder types", () => {
// Act
const strict = getPrimitiveUnionMatcher<"a" | "b">();
const widening = getPrimitiveUnionMatcherW<"a" | "b">();
// Assert
expectTypeOf(strict).toEqualTypeOf<PrimitiveUnionMatcher<"a" | "b">>();
assert.equal(typeof strict, "function");
expectTypeOf(widening).toEqualTypeOf<PrimitiveUnionMatcherW<"a" | "b">>();
assert.equal(typeof widening, "function");
});
test("index: the tagged-union factories return the exported factory types", () => {
// Act
const strict = getTaggedUnionMatcher<Shape>();
const widening = getTaggedUnionMatcherW<Shape>();
// Assert
expectTypeOf(strict).toEqualTypeOf<TaggedUnionMatcherFactory<Shape>>();
assert.equal(typeof strict, "function");
expectTypeOf(widening).toEqualTypeOf<TaggedUnionMatcherWFactory<Shape>>();
assert.equal(typeof widening, "function");
});
test("index: the tagged-union key step returns the exported builder types", () => {
// Act
const strict = getTaggedUnionMatcher<Shape>()("kind");
const widening = getTaggedUnionMatcherW<Shape>()("kind");
// Assert
expectTypeOf(strict).toEqualTypeOf<TaggedUnionMatcher<Shape, "kind">>();
assert.equal(typeof strict, "function");
expectTypeOf(widening).toEqualTypeOf<TaggedUnionMatcherW<Shape, "kind">>();
assert.equal(typeof widening, "function");
});
+2 -12
View File
@@ -1,8 +1,8 @@
/**
* The public entry point of `tiny-pattern-ts`.
*
* Exports the four matcher factories and the builder types they return.
* Everything else in `src/` is an implementation detail.
* Exports the four matcher factories and nothing else; the builder types they
* return and the rest of `src/` are implementation detail.
*
* @module
*/
@@ -10,17 +10,7 @@ export {
getPrimitiveUnionMatcher,
getPrimitiveUnionMatcherW,
} from "./primitive-union.ts";
export type {
PrimitiveUnionMatcher,
PrimitiveUnionMatcherW,
} from "./primitive-union.ts";
export {
getTaggedUnionMatcher,
getTaggedUnionMatcherW,
} from "./tagged-union.ts";
export type {
TaggedUnionMatcher,
TaggedUnionMatcherFactory,
TaggedUnionMatcherW,
TaggedUnionMatcherWFactory,
} from "./tagged-union.ts";
+4 -18
View File
@@ -44,14 +44,7 @@ type MustBePartial<T extends Matchable, Handled> =
// Strict returns: one common `R`. Overload order is load-bearing:
// #1 Handlers (first) -> the exhaustive form and the autocomplete popup
// #2 Fallback (last) -> accepts a partial handler map plus a fallback
/**
* The builder returned by {@link getPrimitiveUnionMatcher}: call it with a
* handler map for every member of `T` to get a strict matcher, or with a partial
* map plus a fallback.
*
* @typeParam T - The finite universe of primitive members to match.
*/
export interface PrimitiveUnionMatcher<T extends Matchable> {
interface PrimitiveUnionMatcherStrict<T extends Matchable> {
<R>(handlers: Handlers<T, R> & UniverseGate<T>): UnaryFn<T, R>;
<
R,
@@ -66,14 +59,7 @@ export interface PrimitiveUnionMatcher<T extends Matchable> {
// Widened returns: the union of every handler's return type. `P` is inferred
// from the whole handler map, whose closed constraint supplies the
// contextual/autocomplete type.
/**
* The builder returned by {@link getPrimitiveUnionMatcherW}: like
* {@link PrimitiveUnionMatcher}, but the result's return type is the union of
* every handler's return type instead of one common `R`.
*
* @typeParam T - The finite universe of primitive members to match.
*/
export interface PrimitiveUnionMatcherW<T extends Matchable> {
interface PrimitiveUnionMatcherWidening<T extends Matchable> {
<P extends Exact<Handlers<T, unknown>, P>>(
handlers: P & UniverseGate<T>,
): UnaryFn<T, PatternReturns<P>>;
@@ -130,7 +116,7 @@ const dispatch =
*/
export const getPrimitiveUnionMatcher = <
T extends Matchable,
>(): PrimitiveUnionMatcher<T> => dispatch;
>(): PrimitiveUnionMatcherStrict<T> => dispatch;
/**
* Create a matcher for a finite primitive universe whose return type is the
@@ -151,4 +137,4 @@ export const getPrimitiveUnionMatcher = <
*/
export const getPrimitiveUnionMatcherW = <
T extends Matchable,
>(): PrimitiveUnionMatcherW<T> => dispatch;
>(): PrimitiveUnionMatcherWidening<T> => dispatch;
+7 -37
View File
@@ -87,15 +87,7 @@ type MustBePartial<T extends object, K extends keyof T, Handled> =
// Strict returns: one common `R`. Overload order is load-bearing:
// #1 Handlers (first) -> the exhaustive form and the autocomplete popup
// #2 Fallback (last) -> accepts a partial handler map plus a fallback
/**
* The builder returned by the key step of {@link getTaggedUnionMatcher}: call it
* with a handler map for every tag under `K` to get a strict matcher, or with a
* partial map plus a fallback.
*
* @typeParam T - The discriminated-union type to match.
* @typeParam K - The discriminant property of `T`.
*/
export interface TaggedUnionMatcher<T extends object, K extends keyof T> {
interface TaggedUnionMatcherStrict<T extends object, K extends keyof T> {
<R>(handlers: Handlers<T, K, R> & UniverseGate<Tags<T, K>>): UnaryFn<T, R>;
<
R,
@@ -112,15 +104,7 @@ export interface TaggedUnionMatcher<T extends object, K extends keyof T> {
// Widened returns: the union of every handler's return type. `P` is inferred
// from the whole handler map, whose closed constraint supplies the
// contextual/autocomplete type.
/**
* The builder returned by the key step of {@link getTaggedUnionMatcherW}: like
* {@link TaggedUnionMatcher}, but the result's return type is the union of every
* handler's return type instead of one common `R`.
*
* @typeParam T - The discriminated-union type to match.
* @typeParam K - The discriminant property of `T`.
*/
export interface TaggedUnionMatcherW<T extends object, K extends keyof T> {
interface TaggedUnionMatcherWidening<T extends object, K extends keyof T> {
<P extends Exact<Handlers<T, K, unknown>, P>>(
handlers: P & UniverseGate<Tags<T, K>>,
): UnaryFn<T, PatternReturns<P>>;
@@ -137,29 +121,15 @@ export interface TaggedUnionMatcherW<T extends object, K extends keyof T> {
// The key-taking step of the curried factory. Naming it lets the factory return
// `dispatch` directly, the tacit twin of the primitive-union factory's bare
// `=> dispatch`.
/**
* The function returned by {@link getTaggedUnionMatcher}: call it with the
* discriminant property's name to get the handler-map builder.
*
* @typeParam T - The discriminated-union type to match.
*/
export type TaggedUnionMatcherFactory<T extends object> = <
K extends Discriminated<T>,
>(
type TaggedUnionMatcherFactory<T extends object> = <K extends Discriminated<T>>(
k: K,
) => TaggedUnionMatcher<T, K>;
) => TaggedUnionMatcherStrict<T, K>;
/**
* The function returned by {@link getTaggedUnionMatcherW}: call it with the
* discriminant property's name to get the widening handler-map builder.
*
* @typeParam T - The discriminated-union type to match.
*/
export type TaggedUnionMatcherWFactory<T extends object> = <
type TaggedUnionMatcherWideningFactory<T extends object> = <
K extends Discriminated<T>,
>(
k: K,
) => TaggedUnionMatcherW<T, K>;
) => TaggedUnionMatcherWidening<T, K>;
const dispatch =
(k: PropertyKey) =>
@@ -227,4 +197,4 @@ export const getTaggedUnionMatcher = <
*/
export const getTaggedUnionMatcherW = <
T extends object,
>(): TaggedUnionMatcherWFactory<T> => dispatch;
>(): TaggedUnionMatcherWideningFactory<T> => dispatch;