ts-pattern
Advanced tools
Comparing version 0.1.8 to 0.1.9
@@ -0,1 +1,2 @@ | ||
import { ValueOf, LeastUpperBound, ExcludeIfContainsNever, UnionToIntersection } from './types/helpers'; | ||
/** | ||
@@ -9,3 +10,4 @@ * # Pattern matching | ||
Guard = "@match/guard", | ||
Not = "@match/not" | ||
Not = "@match/not", | ||
Select = "@match/select" | ||
} | ||
@@ -49,2 +51,6 @@ /** | ||
}; | ||
declare type SelectPattern<k extends string> = { | ||
patternKind: PatternType.Select; | ||
key: k; | ||
}; | ||
declare type SpecialPattern<a> = a extends number ? typeof __.number | __ : a extends string ? typeof __.string | __ : a extends boolean ? typeof __.boolean | __ : __; | ||
@@ -56,4 +62,4 @@ /** | ||
*/ | ||
export declare type Pattern<a> = GuardPattern<a> | NotPattern<a | any> | SpecialPattern<a> | (a extends Primitives ? a : a extends [infer b, infer c, infer d, infer e, infer f] ? readonly [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>, Pattern<f>] : a extends [infer b, infer c, infer d, infer e] ? readonly [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>] : a extends [infer b, infer c, infer d] ? readonly [Pattern<b>, Pattern<c>, Pattern<d>] : a extends [infer b, infer c] ? readonly [Pattern<b>, Pattern<c>] : a extends (infer b)[] ? readonly Pattern<b>[] : a extends Map<infer k, infer v> ? Map<k, Pattern<v>> : a extends Set<infer v> ? Set<Pattern<v>> : a extends object ? { | ||
readonly [k in keyof a]?: Pattern<a[k]>; | ||
export declare type Pattern<a> = SelectPattern<string> | GuardPattern<a> | NotPattern<a | any> | SpecialPattern<a> | (a extends Primitives ? a : 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>> : a extends object ? { | ||
[k in keyof a]?: Pattern<a[k]>; | ||
} : a); | ||
@@ -65,35 +71,49 @@ /** | ||
*/ | ||
declare type InvertPattern<p> = p extends typeof __.number ? number : p extends typeof __.string ? string : p extends typeof __.boolean ? boolean : p extends __ ? __ : p extends GuardPattern<infer pb> ? GuardValue<p['when']> : p extends NotPattern<infer pb> ? { | ||
declare type InvertPattern<p> = p extends typeof __.number ? number : p extends typeof __.string ? string : p extends typeof __.boolean ? boolean : p extends SelectPattern<string> ? __ : p extends __ ? __ : p extends GuardPattern<infer pb> ? GuardValue<p['when']> : p extends NotPattern<infer pb> ? { | ||
valueKind: PatternType.Not; | ||
value: InvertPattern<pb>; | ||
} : p extends Primitives ? p : p extends readonly [infer pb, infer pc, infer pd, infer pe, infer pf] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>, InvertPattern<pe>, InvertPattern<pf>] : p extends readonly [infer pb, infer pc, infer pd, infer pe] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>, InvertPattern<pe>] : p extends readonly [infer pb, infer pc, infer pd] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>] : p extends readonly [infer pb, infer pc] ? [InvertPattern<pb>, InvertPattern<pc>] : p extends readonly (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 object ? { | ||
} : p extends Primitives ? p : 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 object ? { | ||
[k in keyof p]: InvertPattern<p[k]>; | ||
} : p; | ||
/** | ||
* ### LeastUpperBound | ||
* An interesting one. A type taking two imbricated sets and returning the | ||
* smallest one. | ||
* We need that because sometimes the pattern's infered type holds more | ||
* information than the value on which we are matching (if the value is any | ||
* or unknown for instance). | ||
*/ | ||
declare type LeastUpperBound<a, b> = b extends a ? b : a extends b ? a : never; | ||
declare type ExtractMostPreciseValue<a, b> = b extends [] ? [] : [a, b] extends [[infer a1, infer a2, infer a3, infer a4, infer a5] | infer otherBranches, [infer b1, infer b2, infer b3, infer b4, infer b5]] ? [ExtractMostPreciseValue<a1, b1>, ExtractMostPreciseValue<a2, b2>, ExtractMostPreciseValue<a3, b3>, ExtractMostPreciseValue<a4, b4>, ExtractMostPreciseValue<a5, b5>] : [a, b] extends [[infer a1, infer a2, infer a3, infer a4] | infer otherBranches, [infer b1, infer b2, infer b3, infer b4]] ? [ExtractMostPreciseValue<a1, b1>, ExtractMostPreciseValue<a2, b2>, ExtractMostPreciseValue<a3, b3>, ExtractMostPreciseValue<a4, b4>] : [a, b] extends [[infer a1, infer a2, infer a3] | infer otherBranches, [infer b1, infer b2, infer b3]] ? [ExtractMostPreciseValue<a1, b1>, ExtractMostPreciseValue<a2, b2>, ExtractMostPreciseValue<a3, b3>] : [a, b] extends [[infer a1, infer a2] | infer otherBranches, [infer b1, infer b2]] ? [ExtractMostPreciseValue<a1, b1>, ExtractMostPreciseValue<a2, b2>] : [a, b] extends [(infer a1)[], (infer b1)[]] ? ExtractMostPreciseValue<a1, b1>[] : [a, b] extends [Map<infer ak, infer av>, Map<infer bk, infer bv>] ? Map<ExtractMostPreciseValue<ak, bk>, ExtractMostPreciseValue<av, bv>> : [a, b] extends [Set<infer av>, Set<infer bv>] ? Set<ExtractMostPreciseValue<av, bv>> : b extends __ ? a : b extends { | ||
valueKind: PatternType.Not; | ||
value: infer b1; | ||
} ? Exclude<a, b1> extends never ? a : Exclude<a, b1> : b extends object ? ObjectExtractMostPreciseValue<a, b> : LeastUpperBound<a, b>; | ||
/** | ||
* if a key of an object has the never type, | ||
* returns never, otherwise returns the type of object | ||
**/ | ||
declare type ExcludeIfContainsNever<a> = ValueOf<{ | ||
[k in keyof a]: a[k] extends never ? 'exclude' : 'include'; | ||
}> extends 'include' ? a : never; | ||
} ? Exclude<a, b1> : b extends object ? ObjectExtractMostPreciseValue<a, b> : LeastUpperBound<a, b>; | ||
declare type ObjectExtractMostPreciseValue<a, b> = b extends a ? b : a extends b ? a : ExcludeIfContainsNever<{ | ||
[k in keyof a]-?: k extends keyof b ? ExtractMostPreciseValue<a[k], b[k]> : a[k]; | ||
[k in keyof Required<a>]: k extends keyof b ? ExtractMostPreciseValue<a[k], b[k]> : a[k]; | ||
}>; | ||
declare type ValueOf<a> = a[keyof a]; | ||
declare type MatchedValue<a, p extends Pattern<a>> = ExtractMostPreciseValue<a, InvertPattern<p>>; | ||
declare type MatchedValue<a, p extends Pattern<a>> = ExtractMostPreciseValue<a, InvertPattern<p>> extends never ? a : ExtractMostPreciseValue<a, InvertPattern<p>>; | ||
declare type FindSelected<a, b> = b extends SelectPattern<infer Key> ? { | ||
[k in Key]: a; | ||
} : [a, b] extends [object, object] ? ValueOf<{ | ||
[k in keyof a & keyof b]: FindSelected1<a[k], b[k]>; | ||
}> : never; | ||
declare type FindSelected1<a, b> = b extends SelectPattern<infer Key> ? { | ||
[k in Key]: a; | ||
} : [a, b] extends [object, object] ? ValueOf<{ | ||
[k in keyof a & keyof b]: FindSelected2<a[k], b[k]>; | ||
}> : never; | ||
declare type FindSelected2<a, b> = b extends SelectPattern<infer Key> ? { | ||
[k in Key]: a; | ||
} : [a, b] extends [object, object] ? ValueOf<{ | ||
[k in keyof a & keyof b]: FindSelected3<a[k], b[k]>; | ||
}> : never; | ||
declare type FindSelected3<a, b> = b extends SelectPattern<infer Key> ? { | ||
[k in Key]: a; | ||
} : [a, b] extends [object, object] ? ValueOf<{ | ||
[k in keyof a & keyof b]: FindSelected4<a[k], b[k]>; | ||
}> : never; | ||
declare type FindSelected4<a, b> = b extends SelectPattern<infer Key> ? { | ||
[k in Key]: a; | ||
} : [a, b] extends [object, object] ? ValueOf<{ | ||
[k in keyof a & keyof b]: FindSelected5<a[k], b[k]>; | ||
}> : never; | ||
declare type FindSelected5<a, b> = b extends SelectPattern<infer Key> ? { | ||
[k in Key]: a; | ||
} : never; | ||
declare type ToHandler<a, b, c> = (value: a, selections: UnionToIntersection<FindSelected<a, b>>) => c; | ||
declare type PatternHandler<a, b extends Pattern<a>, c> = ToHandler<MatchedValue<a, b>, b, c>; | ||
export declare const when: <a>(predicate: GuardFunction<a>) => GuardPattern<a>; | ||
export declare const not: <a>(pattern: Pattern<a>) => NotPattern<a>; | ||
export declare const select: <k extends string>(key: k) => SelectPattern<k>; | ||
/** | ||
@@ -115,3 +135,3 @@ * ### match | ||
**/ | ||
with: <p extends Pattern<a>>(pattern: p, handler: (value: MatchedValue<a, p>) => b) => Match<a, b>; | ||
with: <p extends Pattern<a>>(pattern: p, handler: PatternHandler<a, p, b>) => Match<a, b>; | ||
/** | ||
@@ -118,0 +138,0 @@ * ### Match.when |
"use strict"; | ||
/** | ||
* # Pattern matching | ||
**/ | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -26,3 +23,6 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
exports.__esModule = true; | ||
exports.match = exports.not = exports.when = exports.__ = void 0; | ||
exports.match = exports.select = exports.not = exports.when = exports.__ = void 0; | ||
/** | ||
* # Pattern matching | ||
**/ | ||
var PatternType; | ||
@@ -35,2 +35,3 @@ (function (PatternType) { | ||
PatternType["Not"] = "@match/not"; | ||
PatternType["Select"] = "@match/select"; | ||
})(PatternType || (PatternType = {})); | ||
@@ -66,2 +67,6 @@ /** | ||
}); }; | ||
exports.select = function (key) { return ({ | ||
patternKind: PatternType.Select, | ||
key: key | ||
}); }; | ||
/** | ||
@@ -82,5 +87,19 @@ * ### match | ||
"with": function (pattern, handler) { | ||
return builder(value, __spread(patterns, [[matchPattern(pattern), handler]])); | ||
return builder(value, __spread(patterns, [ | ||
{ | ||
test: matchPattern(pattern), | ||
handler: handler, | ||
select: selectWithPattern(pattern) | ||
}, | ||
])); | ||
}, | ||
when: function (predicate, handler) { return builder(value, __spread(patterns, [[predicate, handler]])); }, | ||
when: function (predicate, handler) { | ||
return builder(value, __spread(patterns, [ | ||
{ | ||
test: predicate, | ||
handler: handler, | ||
select: function () { return ({}); } | ||
}, | ||
])); | ||
}, | ||
withWhen: function (pattern, predicate, handler) { | ||
@@ -90,19 +109,28 @@ var doesMatch = function (value) { | ||
}; | ||
return builder(value, __spread(patterns, [[doesMatch, handler]])); | ||
return builder(value, __spread(patterns, [ | ||
{ | ||
test: doesMatch, | ||
handler: handler, | ||
select: function () { return ({}); } | ||
}, | ||
])); | ||
}, | ||
otherwise: function (handler) { | ||
return builder(value, __spread(patterns, [ | ||
[matchPattern(exports.__), handler], | ||
{ | ||
test: matchPattern(exports.__), | ||
handler: handler, | ||
select: function () { return ({}); } | ||
}, | ||
])); | ||
}, | ||
run: function () { | ||
var tupple = patterns.find(function (_a) { | ||
var _b = __read(_a, 1), predicate = _b[0]; | ||
return predicate(value); | ||
var entry = patterns.find(function (_a) { | ||
var test = _a.test; | ||
return test(value); | ||
}); | ||
if (!tupple) { | ||
if (!entry) { | ||
throw new Error("Pattern matching error: no pattern matches value " + value); | ||
} | ||
var _a = __read(tupple, 2), mapper = _a[1]; | ||
return mapper(value); | ||
return entry.handler(value, entry.select(value)); | ||
} | ||
@@ -123,5 +151,9 @@ }); }; | ||
}; | ||
var isSelectPattern = function (x) { | ||
var pattern = x; | ||
return pattern && pattern.patternKind === PatternType.Select; | ||
}; | ||
// tells us if the value matches a given pattern. | ||
var matchPattern = function (pattern) { return function (value) { | ||
if (pattern === exports.__) | ||
if (pattern === exports.__ || isSelectPattern(pattern)) | ||
return true; | ||
@@ -176,1 +208,18 @@ if (pattern === exports.__.string) | ||
}; }; | ||
var selectWithPattern = function (pattern) { return function (value) { | ||
var _a; | ||
if (isSelectPattern(pattern)) | ||
return _a = {}, _a[pattern.key] = value, _a; | ||
if (Array.isArray(pattern) && Array.isArray(value)) | ||
return pattern.length === 1 | ||
? value.reduce(function (acc, v) { return Object.assign(acc, selectWithPattern(pattern[0])(v)); }, {}) | ||
: pattern.length === value.length | ||
? value.reduce(function (acc, v, i) { return Object.assign(acc, selectWithPattern(pattern[i])(v)); }, {}) | ||
: {}; | ||
if (isObject(pattern) && isObject(value)) | ||
return Object.keys(pattern).reduce(function (acc, k) { | ||
// @ts-ignore | ||
return Object.assign(acc, selectWithPattern(pattern[k])(value[k])); | ||
}, {}); | ||
return {}; | ||
}; }; |
{ | ||
"name": "ts-pattern", | ||
"version": "0.1.8", | ||
"version": "0.1.9", | ||
"description": "Typescript pattern matching library", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21606
6
404