Replace the three `/* */` prose blocks with `//` line comments, matching the rest of the codebase and the comment style the oxlint config now allows.
72 lines
3.0 KiB
TypeScript
72 lines
3.0 KiB
TypeScript
import type { Simplify, ValueOf } from "type-fest";
|
|
|
|
type UnaryFn<T, R> = (shape: T) => R;
|
|
|
|
// ============================================================================
|
|
// ✔️ Exhaustive
|
|
// ❌ ReturnsStrict
|
|
// ============================================================================
|
|
type PatternPrimitiveUnion<R, T extends string | number> = {
|
|
[K in T]: UnaryFn<K, R>;
|
|
};
|
|
|
|
type PatternReturns<
|
|
P extends Record<string | number, UnaryFn<never, unknown>>,
|
|
> = ReturnType<ValueOf<P>>;
|
|
|
|
export const getPrimitiveUnionMatcherW: <T extends string | number>() => <
|
|
P extends PatternPrimitiveUnion<unknown, T>,
|
|
>(
|
|
pattern: Simplify<P>,
|
|
) => UnaryFn<T, PatternReturns<P>> = () => (pattern) => (shape) =>
|
|
// Rewrite not to use any is possible, was evaluated and solutions were
|
|
// more complex than the current solution.
|
|
|
|
// oxlint-disable-next-line typescript/no-explicit-any typescript/no-unsafe-type-assertion
|
|
(pattern[shape] as any)(shape);
|
|
|
|
// ============================================================================
|
|
// ✔️ Exhaustive
|
|
// ✔️ ReturnsStrict
|
|
// ============================================================================
|
|
export const getPrimitiveUnionMatcher: <T extends string | number>() => <R>(
|
|
pattern: Simplify<PatternPrimitiveUnion<R, T>>,
|
|
) => UnaryFn<T, R> = getPrimitiveUnionMatcherW;
|
|
|
|
// ============================================================================
|
|
// ❌ Exhaustive
|
|
// ✔️ ReturnsStrict
|
|
// ============================================================================
|
|
type PatternPrimitiveUnionPartial<R, T extends string | number> =
|
|
| PatternPrimitiveUnion<R, T>
|
|
| (Partial<PatternPrimitiveUnion<R, T>> & {
|
|
_: UnaryFn<T, R>;
|
|
});
|
|
|
|
export const getPrimitiveUnionMatcherPartial: <T extends string | number>() => <
|
|
R,
|
|
>(
|
|
pattern: Simplify<PatternPrimitiveUnionPartial<R, T>>,
|
|
) => UnaryFn<T, R> = () => (pattern) => (shape) =>
|
|
// Rewrite not to use any is possible, was evaluated and solutions were
|
|
// more complex than the current solution.
|
|
|
|
// oxlint-disable-next-line typescript/no-explicit-any typescript/no-unsafe-type-assertion
|
|
(pattern[shape] ?? (pattern as any)["_"])(shape);
|
|
|
|
// ============================================================================
|
|
// ❌ Exhaustive
|
|
// ❌ ReturnsStrict
|
|
// ============================================================================
|
|
export const getPrimitiveUnionMatcherPartialW: <
|
|
T extends string | number,
|
|
>() => <P extends PatternPrimitiveUnionPartial<unknown, T>>(
|
|
// `Simplify<P>` is the inference hook: callers infer `P` from the argument.
|
|
// the second half pins the impl parameter's `R` to `PatternReturns<P>`.
|
|
// that makes the `= getPrimitiveUnionMatcherPartial` assignment type-check.
|
|
// neither half works alone.
|
|
// without the witness the union's `_` arm demands `_ ∈ keyof P`.
|
|
// without `Simplify<P>` the parameter types do not compare.
|
|
pattern: Simplify<P> & PatternPrimitiveUnionPartial<PatternReturns<P>, T>,
|
|
) => UnaryFn<T, PatternReturns<P>> = getPrimitiveUnionMatcherPartial;
|