|
| 1 | +/** |
| 2 | + * # Pattern matching |
| 3 | + **/ |
| 4 | +/** |
| 5 | + * ## Catch All Type |
| 6 | + * `__` refers to a wildcard pattern matching any value |
| 7 | + */ |
| 8 | +declare type __ = '__CATCH_ALL__'; |
| 9 | +export declare const __: __; |
| 10 | +/** |
| 11 | + * ## Pattern |
| 12 | + * Patterns can be any (nested) javascript value. |
| 13 | + * They can also be "wildcards", using type constructors |
| 14 | + */ |
| 15 | +export declare type Pattern<a> = a extends number ? a | NumberConstructor | __ : a extends string ? a | StringConstructor | __ : a extends boolean ? a | BooleanConstructor | __ : a extends [infer b, infer c, infer d, infer e, infer f] ? [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>, Pattern<f>] | __ : a extends [infer b, infer c, infer d, infer e] ? [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>] | __ : a extends [infer b, infer c, infer d] ? [Pattern<b>, Pattern<c>, Pattern<d>] | __ : a extends [infer b, infer c] ? [Pattern<b>, Pattern<c>] | __ : a extends (infer b)[] ? Pattern<b>[] | __ : a extends Map<infer k, infer v> ? Map<k, Pattern<v>> | __ : a extends Set<infer v> ? Set<Pattern<v>> | __ : { |
| 16 | + [k in keyof a]?: Pattern<a[k]>; |
| 17 | +} | __; |
| 18 | +/** |
| 19 | + * ## Invert Pattern |
| 20 | + * Since patterns have special wildcard values, we need a way |
| 21 | + * to transform a pattern into the type of value it represents |
| 22 | + */ |
| 23 | +export declare type InvertPattern<p> = p extends NumberConstructor ? number : p extends StringConstructor ? string : p extends BooleanConstructor ? boolean : p extends [infer pb, infer pc, infer pd, infer pe, infer pf] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>, InvertPattern<pe>, InvertPattern<pf>] : p extends [infer pb, infer pc, infer pd, infer pe] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>, InvertPattern<pe>] : p extends [infer pb, infer pc, infer pd] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>] : p extends [infer pb, infer pc] ? [InvertPattern<pb>, InvertPattern<pc>] : p extends (infer pp)[] ? InvertPattern<pp>[] : p extends Map<infer pk, infer pv> ? Map<pk, InvertPattern<pv>> : p extends Set<infer pv> ? Set<InvertPattern<pv>> : p extends __ ? __ : { |
| 24 | + [k in keyof p]: InvertPattern<p[k]>; |
| 25 | +}; |
| 26 | +declare type Fun<a, b> = (value: a) => b; |
| 27 | +/** |
| 28 | + * ## LeastUpperBound |
| 29 | + * An interesting one. A type taking two imbricated sets and returning the |
| 30 | + * smallest one. |
| 31 | + * We need that because sometimes the pattern's infered type holds more |
| 32 | + * information than the value on which we are matching (if the value is any |
| 33 | + * or unknown for instance). |
| 34 | + */ |
| 35 | +declare type LeastUpperBound<a, b> = [a, b] extends [[infer aa, infer ab, infer ac, infer ad, infer ae], [infer ba, infer bb, infer bc, infer bd, infer be]] ? [LeastUpperBound<aa, ba>, LeastUpperBound<ab, bb>, LeastUpperBound<ac, bc>, LeastUpperBound<ad, bd>, LeastUpperBound<ae, be>] : [a, b] extends [[infer aa, infer ab, infer ac, infer ad], [infer ba, infer bb, infer bc, infer bd]] ? [LeastUpperBound<aa, ba>, LeastUpperBound<ab, bb>, LeastUpperBound<ac, bc>, LeastUpperBound<ad, bd>] : [a, b] extends [[infer aa, infer ab, infer ac], [infer ba, infer bb, infer bc]] ? [LeastUpperBound<aa, ba>, LeastUpperBound<ab, bb>, LeastUpperBound<ac, bc>] : [a, b] extends [[infer aa, infer ab], [infer ba, infer bb]] ? [LeastUpperBound<aa, ba>, LeastUpperBound<ab, bb>] : [a, b] extends [(infer aa)[], (infer ba)[]] ? LeastUpperBound<aa, ba>[] : [a, b] extends [Map<infer ak, infer av>, Map<infer bk, infer bv>] ? Map<LeastUpperBound<ak, bk>, LeastUpperBound<av, bv>> : [a, b] extends [Set<infer av>, Set<infer bv>] ? Set<LeastUpperBound<av, bv>> : b extends __ ? a : a extends __ ? b : b extends a ? b : a extends b ? a : never; |
| 36 | +/** |
| 37 | + * ## match |
| 38 | + * Entry point to create pattern matching code branches. It returns an |
| 39 | + * empty builder |
| 40 | + */ |
| 41 | +export declare const match: <a, b>(value: a) => { |
| 42 | + with: <p extends Pattern<a>>(pattern: p, f: Fun<LeastUpperBound<a, InvertPattern<p>>, b>) => any; |
| 43 | + when: (predicate: Fun<a, unknown>, f: Fun<a, b>) => any; |
| 44 | + withWhen: <p_1 extends Pattern<a>>(pattern: p_1, predicate: Fun<LeastUpperBound<a, InvertPattern<p_1>>, unknown>, f: Fun<LeastUpperBound<a, InvertPattern<p_1>>, b>) => any; |
| 45 | + otherwise: (f: () => b) => any; |
| 46 | + run: () => b; |
| 47 | +}; |
| 48 | +export {}; |
0 commit comments