All files primitive.ts

100% Statements 71/71
100% Branches 8/8
100% Functions 2/2
100% Lines 71/71

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 721x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 16x 16x 16x 16x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 18x 18x 18x 18x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
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;