From 6acc1d3c661be66f67df322063f9052794899b80 Mon Sep 17 00:00:00 2001 From: Trevor Smith Date: Fri, 4 Oct 2024 08:42:49 -0600 Subject: [PATCH 1/2] Export additional useful types --- src/types/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/types/index.ts b/src/types/index.ts index 230069f4..3b5ae5a7 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1 +1,6 @@ +export * from './ExtractPreciseValue'; +export * from './FindSelected'; +export * from './InvertPattern'; +export * from './IsMatching'; +export * from './Match'; export * from './Pattern'; \ No newline at end of file From 708e4c62dfea2cf192b62b5866522b97aa1f135d Mon Sep 17 00:00:00 2001 From: Trevor Smith Date: Mon, 7 Oct 2024 21:57:40 -0600 Subject: [PATCH 2/2] Add dist folder --- .gitignore | 1 - dist/errors.d.cts | 8 + dist/errors.d.ts | 8 + dist/index.cjs | 2 + dist/index.cjs.map | 1 + dist/index.d.cts | 5 + dist/index.d.ts | 5 + dist/index.js | 2 + dist/index.js.map | 1 + dist/index.umd.js | 2 + dist/index.umd.js.map | 1 + dist/internals/helpers.d.cts | 12 + dist/internals/helpers.d.ts | 12 + dist/internals/symbols.d.cts | 24 ++ dist/internals/symbols.d.ts | 24 ++ dist/is-matching.d.cts | 32 +++ dist/is-matching.d.ts | 32 +++ dist/match.d.cts | 19 ++ dist/match.d.ts | 19 ++ dist/patterns.d.cts | 302 ++++++++++++++++++++ dist/patterns.d.ts | 302 ++++++++++++++++++++ dist/types/BuildMany.d.cts | 16 ++ dist/types/BuildMany.d.ts | 16 ++ dist/types/DeepExclude.d.cts | 2 + dist/types/DeepExclude.d.ts | 2 + dist/types/DistributeUnions.d.cts | 111 ++++++++ dist/types/DistributeUnions.d.ts | 111 ++++++++ dist/types/ExtractPreciseValue.d.cts | 27 ++ dist/types/ExtractPreciseValue.d.ts | 27 ++ dist/types/FindSelected.d.cts | 65 +++++ dist/types/FindSelected.d.ts | 65 +++++ dist/types/InvertPattern.d.cts | 102 +++++++ dist/types/InvertPattern.d.ts | 102 +++++++ dist/types/IsMatching.d.cts | 13 + dist/types/IsMatching.d.ts | 13 + dist/types/Match.d.cts | 129 +++++++++ dist/types/Match.d.ts | 129 +++++++++ dist/types/Pattern.d.cts | 396 +++++++++++++++++++++++++++ dist/types/Pattern.d.ts | 396 +++++++++++++++++++++++++++ dist/types/helpers.d.cts | 77 ++++++ dist/types/helpers.d.ts | 77 ++++++ dist/types/index.d.cts | 6 + dist/types/index.d.ts | 6 + 43 files changed, 2701 insertions(+), 1 deletion(-) create mode 100644 dist/errors.d.cts create mode 100644 dist/errors.d.ts create mode 100644 dist/index.cjs create mode 100644 dist/index.cjs.map create mode 100644 dist/index.d.cts create mode 100644 dist/index.d.ts create mode 100644 dist/index.js create mode 100644 dist/index.js.map create mode 100644 dist/index.umd.js create mode 100644 dist/index.umd.js.map create mode 100644 dist/internals/helpers.d.cts create mode 100644 dist/internals/helpers.d.ts create mode 100644 dist/internals/symbols.d.cts create mode 100644 dist/internals/symbols.d.ts create mode 100644 dist/is-matching.d.cts create mode 100644 dist/is-matching.d.ts create mode 100644 dist/match.d.cts create mode 100644 dist/match.d.ts create mode 100644 dist/patterns.d.cts create mode 100644 dist/patterns.d.ts create mode 100644 dist/types/BuildMany.d.cts create mode 100644 dist/types/BuildMany.d.ts create mode 100644 dist/types/DeepExclude.d.cts create mode 100644 dist/types/DeepExclude.d.ts create mode 100644 dist/types/DistributeUnions.d.cts create mode 100644 dist/types/DistributeUnions.d.ts create mode 100644 dist/types/ExtractPreciseValue.d.cts create mode 100644 dist/types/ExtractPreciseValue.d.ts create mode 100644 dist/types/FindSelected.d.cts create mode 100644 dist/types/FindSelected.d.ts create mode 100644 dist/types/InvertPattern.d.cts create mode 100644 dist/types/InvertPattern.d.ts create mode 100644 dist/types/IsMatching.d.cts create mode 100644 dist/types/IsMatching.d.ts create mode 100644 dist/types/Match.d.cts create mode 100644 dist/types/Match.d.ts create mode 100644 dist/types/Pattern.d.cts create mode 100644 dist/types/Pattern.d.ts create mode 100644 dist/types/helpers.d.cts create mode 100644 dist/types/helpers.d.ts create mode 100644 dist/types/index.d.cts create mode 100644 dist/types/index.d.ts diff --git a/.gitignore b/.gitignore index 7679d4c9..ebe940f3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ node_modules npm-debug.log lib -dist notes.md .vscode/ tracing_output_folder/ diff --git a/dist/errors.d.cts b/dist/errors.d.cts new file mode 100644 index 00000000..06cb0726 --- /dev/null +++ b/dist/errors.d.cts @@ -0,0 +1,8 @@ +/** + * Error when the given input value does not match any included pattern + * and .exhaustive() was specified + */ +export declare class NonExhaustiveError extends Error { + input: unknown; + constructor(input: unknown); +} diff --git a/dist/errors.d.ts b/dist/errors.d.ts new file mode 100644 index 00000000..06cb0726 --- /dev/null +++ b/dist/errors.d.ts @@ -0,0 +1,8 @@ +/** + * Error when the given input value does not match any included pattern + * and .exhaustive() was specified + */ +export declare class NonExhaustiveError extends Error { + input: unknown; + constructor(input: unknown); +} diff --git a/dist/index.cjs b/dist/index.cjs new file mode 100644 index 00000000..c7ecdf7e --- /dev/null +++ b/dist/index.cjs @@ -0,0 +1,2 @@ +function n(t){return n=Object.setPrototypeOf?Object.getPrototypeOf:function(n){return n.__proto__||Object.getPrototypeOf(n)},n(t)}function t(n,r){return t=Object.setPrototypeOf||function(n,t){return n.__proto__=t,n},t(n,r)}function r(n,e,u){return r=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(n){return!1}}()?Reflect.construct:function(n,r,e){var u=[null];u.push.apply(u,r);var i=new(Function.bind.apply(n,u));return e&&t(i,e.prototype),i},r.apply(null,arguments)}function e(u){var i="function"==typeof Map?new Map:void 0;return e=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==i){if(i.has(e))return i.get(e);i.set(e,u)}function u(){return r(e,arguments,n(this).constructor)}return u.prototype=Object.create(e.prototype,{constructor:{value:u,enumerable:!1,writable:!0,configurable:!0}}),t(u,e)},e(u)}function u(n,t){(null==t||t>n.length)&&(t=n.length);for(var r=0,e=new Array(t);r=n.length?{done:!0}:{done:!1,value:n[e++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o=Symbol.for("@ts-pattern/matcher"),c=Symbol.for("@ts-pattern/isVariadic"),f="@ts-pattern/anonymous-select-key",a=function(n){return Boolean(n&&"object"==typeof n)},l=function(n){return n&&!!n[o]},s=function n(t,r,e){if(l(t)){var u=t[o]().match(r),f=u.matched,s=u.selections;return f&&s&&Object.keys(s).forEach(function(n){return e(n,s[n])}),f}if(a(t)){if(!a(r))return!1;if(Array.isArray(t)){if(!Array.isArray(r))return!1;for(var h,v=[],p=[],g=[],y=i(t.keys());!(h=y()).done;){var m=t[h.value];l(m)&&m[c]?g.push(m):g.length?p.push(m):v.push(m)}if(g.length){if(g.length>1)throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(r.length=n})}(r)))},length:function(r){return n(w(t,function(n){return S(function(t){return A(t)&&t.length===n})}(r)))},maxLength:function(r){return n(w(t,function(n){return S(function(t){return A(t)&&t.length<=n})}(r)))},includes:function(r){return n(w(t,(e=r,S(function(n){return A(n)&&n.includes(e)}))));var e},regex:function(r){return n(w(t,(e=r,S(function(n){return A(n)&&Boolean(n.match(e))}))));var e}})}(S(A)),T=function n(t){return Object.assign(g(t),{between:function(r,e){return n(w(t,function(n,t){return S(function(r){return x(r)&&n<=r&&t>=r})}(r,e)))},lt:function(r){return n(w(t,function(n){return S(function(t){return x(t)&&tn})}(r)))},lte:function(r){return n(w(t,function(n){return S(function(t){return x(t)&&t<=n})}(r)))},gte:function(r){return n(w(t,function(n){return S(function(t){return x(t)&&t>=n})}(r)))},int:function(){return n(w(t,S(function(n){return x(n)&&Number.isInteger(n)})))},finite:function(){return n(w(t,S(function(n){return x(n)&&Number.isFinite(n)})))},positive:function(){return n(w(t,S(function(n){return x(n)&&n>0})))},negative:function(){return n(w(t,S(function(n){return x(n)&&n<0})))}})}(S(x)),B=function n(t){return Object.assign(g(t),{between:function(r,e){return n(w(t,function(n,t){return S(function(r){return E(r)&&n<=r&&t>=r})}(r,e)))},lt:function(r){return n(w(t,function(n){return S(function(t){return E(t)&&tn})}(r)))},lte:function(r){return n(w(t,function(n){return S(function(t){return E(t)&&t<=n})}(r)))},gte:function(r){return n(w(t,function(n){return S(function(t){return E(t)&&t>=n})}(r)))},positive:function(){return n(w(t,S(function(n){return E(n)&&n>0})))},negative:function(){return n(w(t,S(function(n){return E(n)&&n<0})))}})}(S(E)),M=g(S(function(n){return"boolean"==typeof n})),R=g(S(function(n){return"symbol"==typeof n})),I=g(S(function(n){return null==n})),N=g(S(function(n){return null!=n})),k={__proto__:null,matcher:o,optional:m,array:function(){var n,t=[].slice.call(arguments);return y(((n={})[o]=function(){return{match:function(n){if(!Array.isArray(n))return{matched:!1};if(0===t.length)return{matched:!0};var r=t[0],e={};if(0===n.length)return h(r).forEach(function(n){e[n]=[]}),{matched:!0,selections:e};var u=function(n,t){e[n]=(e[n]||[]).concat([t])};return{matched:n.every(function(n){return s(r,n,u)}),selections:e}},getSelectionKeys:function(){return 0===t.length?[]:h(t[0])}}},n))},set:function(){var n,t=[].slice.call(arguments);return g(((n={})[o]=function(){return{match:function(n){if(!(n instanceof Set))return{matched:!1};var r={};if(0===n.size)return{matched:!0,selections:r};if(0===t.length)return{matched:!0};var e=function(n,t){r[n]=(r[n]||[]).concat([t])},u=t[0];return{matched:d(n,function(n){return s(u,n,e)}),selections:r}},getSelectionKeys:function(){return 0===t.length?[]:h(t[0])}}},n))},map:function(){var n,t=[].slice.call(arguments);return g(((n={})[o]=function(){return{match:function(n){if(!(n instanceof Map))return{matched:!1};var r={};if(0===n.size)return{matched:!0,selections:r};var e,u=function(n,t){r[n]=(r[n]||[]).concat([t])};if(0===t.length)return{matched:!0};if(1===t.length)throw new Error("`P.map` wasn't given enough arguments. Expected (key, value), received "+(null==(e=t[0])?void 0:e.toString()));var i=t[0],o=t[1];return{matched:b(n,function(n,t){var r=s(i,t,u),e=s(o,n,u);return r&&e}),selections:r}},getSelectionKeys:function(){return 0===t.length?[]:[].concat(h(t[0]),h(t[1]))}}},n))},intersection:w,union:O,not:function(n){var t;return g(((t={})[o]=function(){return{match:function(t){return{matched:!s(n,t,function(){})}},getSelectionKeys:function(){return[]},matcherType:"not"}},t))},when:S,select:j,any:_,_:P,string:K,number:T,bigint:B,boolean:M,symbol:R,nullish:I,nonNullable:N,instanceOf:function(n){return g(S(function(n){return function(t){return t instanceof n}}(n)))},shape:function(n){return g(S(p(n)))}},W=/*#__PURE__*/function(n){var r,e;function u(t){var r,e;try{e=JSON.stringify(t)}catch(n){e=t}return(r=n.call(this,"Pattern matching error: no pattern matches value "+e)||this).input=void 0,r.input=t,r}return e=n,(r=u).prototype=Object.create(e.prototype),r.prototype.constructor=r,t(r,e),u}(/*#__PURE__*/e(Error)),F={matched:!1,value:void 0},z=/*#__PURE__*/function(){function n(n,t){this.input=void 0,this.state=void 0,this.input=n,this.state=t}var t=n.prototype;return t.with=function(){var t=this,r=[].slice.call(arguments);if(this.state.matched)return this;var e=r[r.length-1],u=[r[0]],i=void 0;3===r.length&&"function"==typeof r[1]?i=r[1]:r.length>2&&u.push.apply(u,r.slice(1,r.length-1));var o=!1,c={},a=function(n,t){o=!0,c[n]=t},l=!u.some(function(n){return s(n,t.input,a)})||i&&!Boolean(i(this.input))?F:{matched:!0,value:e(o?f in c?c[f]:c:this.input,this.input)};return new n(this.input,l)},t.when=function(t,r){if(this.state.matched)return this;var e=Boolean(t(this.input));return new n(this.input,e?{matched:!0,value:r(this.input,this.input)}:F)},t.otherwise=function(n){return this.state.matched?this.state.value:n(this.input)},t.exhaustive=function(){if(this.state.matched)return this.state.value;throw new W(this.input)},t.run=function(){return this.exhaustive()},t.returnType=function(){return this},n}();exports.NonExhaustiveError=W,exports.P=k,exports.Pattern=k,exports.isMatching=p,exports.match=function(n){return new z(n,F)}; +//# sourceMappingURL=index.cjs.map diff --git a/dist/index.cjs.map b/dist/index.cjs.map new file mode 100644 index 00000000..8ff57d26 --- /dev/null +++ b/dist/index.cjs.map @@ -0,0 +1 @@ +{"version":3,"file":"index.cjs","sources":["../src/internals/symbols.ts","../src/internals/helpers.ts","../src/is-matching.ts","../src/patterns.ts","../src/errors.ts","../src/match.ts"],"sourcesContent":["/**\n * Symbols used internally within ts-pattern to construct and discriminate\n * Guard, Not, and Select, and AnonymousSelect patterns\n *\n * Symbols have the advantage of not appearing in auto-complete suggestions in\n * user defined patterns, and eliminate the risk of property\n * overlap between ts-pattern internals and user defined patterns.\n *\n * These symbols have to be visible to tsc for type inference to work, but\n * users should not import them\n * @module\n * @private\n * @internal\n */\n\nexport const matcher = Symbol.for('@ts-pattern/matcher');\nexport type matcher = typeof matcher;\n\nexport const unset = Symbol.for('@ts-pattern/unset');\nexport type unset = typeof unset;\n\nexport const isVariadic = Symbol.for('@ts-pattern/isVariadic');\nexport type isVariadic = typeof isVariadic;\n\n// can't be a symbol because this key has to be enumerable.\nexport const anonymousSelectKey = '@ts-pattern/anonymous-select-key';\nexport type anonymousSelectKey = typeof anonymousSelectKey;\n\nexport const override = Symbol.for('@ts-pattern/override');\nexport type override = typeof override;\n","/**\n * @module\n * @private\n * @internal\n */\n\nimport * as symbols from './symbols';\nimport { SelectionType } from '../types/FindSelected';\nimport { Pattern, Matcher, MatcherType, AnyMatcher } from '../types/Pattern';\n\n// @internal\nexport const isObject = (value: unknown): value is Object =>\n Boolean(value && typeof value === 'object');\n\n// @internal\nexport const isMatcher = (\n x: unknown\n): x is Matcher => {\n const pattern = x as Matcher;\n return pattern && !!pattern[symbols.matcher];\n};\n\n// @internal\nconst isOptionalPattern = (\n x: unknown\n): x is Matcher => {\n return isMatcher(x) && x[symbols.matcher]().matcherType === 'optional';\n};\n\n// tells us if the value matches a given pattern.\n// @internal\nexport const matchPattern = (\n pattern: any,\n value: any,\n select: (key: string, value: unknown) => void\n): boolean => {\n if (isMatcher(pattern)) {\n const matcher = pattern[symbols.matcher]();\n const { matched, selections } = matcher.match(value);\n if (matched && selections) {\n Object.keys(selections).forEach((key) => select(key, selections[key]));\n }\n return matched;\n }\n\n if (isObject(pattern)) {\n if (!isObject(value)) return false;\n\n // Tuple pattern\n if (Array.isArray(pattern)) {\n if (!Array.isArray(value)) return false;\n let startPatterns = [];\n let endPatterns = [];\n let variadicPatterns: AnyMatcher[] = [];\n\n for (const i of pattern.keys()) {\n const subpattern = pattern[i];\n if (isMatcher(subpattern) && subpattern[symbols.isVariadic]) {\n variadicPatterns.push(subpattern);\n } else if (variadicPatterns.length) {\n endPatterns.push(subpattern);\n } else {\n startPatterns.push(subpattern);\n }\n }\n\n if (variadicPatterns.length) {\n if (variadicPatterns.length > 1) {\n throw new Error(\n `Pattern error: Using \\`...P.array(...)\\` several times in a single pattern is not allowed.`\n );\n }\n\n if (value.length < startPatterns.length + endPatterns.length) {\n return false;\n }\n\n const startValues = value.slice(0, startPatterns.length);\n const endValues =\n endPatterns.length === 0 ? [] : value.slice(-endPatterns.length);\n const middleValues = value.slice(\n startPatterns.length,\n endPatterns.length === 0 ? Infinity : -endPatterns.length\n );\n\n return (\n startPatterns.every((subPattern, i) =>\n matchPattern(subPattern, startValues[i], select)\n ) &&\n endPatterns.every((subPattern, i) =>\n matchPattern(subPattern, endValues[i], select)\n ) &&\n (variadicPatterns.length === 0\n ? true\n : matchPattern(variadicPatterns[0], middleValues, select))\n );\n }\n\n return pattern.length === value.length\n ? pattern.every((subPattern, i) =>\n matchPattern(subPattern, value[i], select)\n )\n : false;\n }\n\n return Reflect.ownKeys(pattern).every((k): boolean => {\n const subPattern = pattern[k];\n\n return (\n (k in value || isOptionalPattern(subPattern)) &&\n matchPattern(subPattern, value[k], select)\n );\n });\n }\n\n return Object.is(value, pattern);\n};\n\n// @internal\nexport const getSelectionKeys = (pattern: any): string[] => {\n if (isObject(pattern)) {\n if (isMatcher(pattern)) {\n return pattern[symbols.matcher]().getSelectionKeys?.() ?? [];\n }\n if (Array.isArray(pattern)) return flatMap(pattern, getSelectionKeys);\n return flatMap(Object.values(pattern), getSelectionKeys);\n }\n return [];\n};\n\n// @internal\nexport const flatMap = (\n xs: readonly a[],\n f: (v: a) => readonly b[]\n): b[] => xs.reduce((acc, x) => acc.concat(f(x)), []);\n","import { MatchedValue, Pattern } from './types/Pattern';\nimport * as P from './patterns';\nimport { matchPattern } from './internals/helpers';\n\n/**\n * `isMatching` takes pattern and returns a **type guard** function, cheching if a value matches this pattern.\n *\n * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching)\n *\n * @example\n * const hasName = isMatching({ name: P.string })\n *\n * declare let input: unknown\n *\n * if (hasName(input)) {\n * // `input` inferred as { name: string }\n * return input.name\n * }\n */\nexport function isMatching>(\n pattern: p\n): (value: unknown) => value is P.infer

;\n/**\n * `isMatching` takes pattern and a value and checks if the value matches this pattern.\n *\n * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching)\n *\n * @example\n * declare let input: unknown\n *\n * if (isMatching({ name: P.string }, input)) {\n * // `input` inferred as { name: string }\n * return input.name\n * }\n */\nexport function isMatching>(\n pattern: p,\n value: unknown\n): value is P.infer

;\n\nexport function isMatching>(\n ...args: [pattern: p, value?: any]\n): boolean | ((vale: any) => boolean) {\n if (args.length === 1) {\n const [pattern] = args;\n return (value: any): value is MatchedValue> =>\n matchPattern(pattern, value, () => {});\n }\n if (args.length === 2) {\n const [pattern, value] = args;\n return matchPattern(pattern, value, () => {});\n }\n\n throw new Error(\n `isMatching wasn't given the right number of arguments: expected 1 or 2, received ${args.length}.`\n );\n}\n","import { matchPattern, getSelectionKeys, flatMap } from './internals/helpers';\nimport * as symbols from './internals/symbols';\nimport { matcher } from './internals/symbols';\nimport { isMatching } from './is-matching';\nimport { ExtractPreciseValue } from './types/ExtractPreciseValue';\nimport { Fn } from './types/helpers';\nimport { InvertPattern } from './types/InvertPattern';\nimport {\n Pattern,\n UnknownPattern,\n OptionalP,\n ArrayP,\n MapP,\n SetP,\n AndP,\n OrP,\n NotP,\n GuardP,\n SelectP,\n AnonymousSelectP,\n GuardExcludeP,\n CustomP,\n Matcher,\n StringPattern,\n AnyPattern,\n NumberPattern,\n BooleanPattern,\n BigIntPattern,\n NullishPattern,\n SymbolPattern,\n Chainable,\n BigIntChainable,\n NumberChainable,\n StringChainable,\n ArrayChainable,\n Variadic,\n NonNullablePattern,\n} from './types/Pattern';\n\nexport type { Pattern, Fn as unstable_Fn };\n\nexport { matcher };\n\n/**\n * @experimental\n * A `Matchable` is an object implementing\n * the Matcher Protocol. It must have a `[P.matcher]: P.Matcher`\n * key, which defines how this object should be matched by TS-Pattern.\n *\n * Note that this api is unstable.\n *\n * @example\n * ```ts\n * class Some implements P.unstable_Matchable {\n * [P.matcher](): P.unstable_Matcher>\n * }\n * ```\n */\nexport type unstable_Matchable<\n narrowedOrFn,\n input = unknown,\n pattern = never\n> = CustomP;\n\n/**\n * @experimental\n * A `Matcher` is an object with `match` function, which\n * defines how this object should be matched by TS-Pattern.\n *\n * Note that this api is unstable.\n *\n * @example\n * ```ts\n * class Some implements P.unstable_Matchable {\n * [P.matcher](): P.unstable_Matcher>\n * }\n * ```\n */\nexport type unstable_Matcher<\n narrowedOrFn,\n input = unknown,\n pattern = never\n> = ReturnType[matcher]>;\n\n/**\n * `P.infer` will return the type of the value\n * matched by this pattern.\n *\n * [Read the documentation for `P.infer` on GitHub](https://github.com/gvergnaud/ts-pattern#pinfer)\n *\n * @example\n * const userPattern = { name: P.string }\n * type User = P.infer\n */\nexport type infer> = InvertPattern<\n pattern,\n unknown\n>;\n\n/**\n * `P.narrow` will narrow the input type to only keep\n * the set of values that are compatible with the provided pattern type.\n *\n * [Read the documentation for `P.narrow` on GitHub](https://github.com/gvergnaud/ts-pattern#pnarrow)\n *\n * @example\n * type Input = ['a' | 'b' | 'c', 'a' | 'b' | 'c']\n * const Pattern = ['a', P.union('a', 'b')] as const\n *\n * type Narrowed = P.narrow\n * // ^? ['a', 'a' | 'b']\n */\nexport type narrow> = ExtractPreciseValue<\n input,\n InvertPattern\n>;\n\nfunction chainable>(\n pattern: pattern\n): Chainable {\n return Object.assign(pattern, {\n optional: () => optional(pattern),\n and: (p2: any) => intersection(pattern, p2),\n or: (p2: any) => union(pattern, p2),\n select: (key: any) =>\n key === undefined ? select(pattern) : select(key, pattern),\n }) as Chainable;\n}\n\nconst variadic = (pattern: pattern): Variadic =>\n Object.assign(pattern, {\n [Symbol.iterator](): Iterator {\n let i = 0;\n const variadicPattern = Object.assign(pattern, {\n [symbols.isVariadic]: true,\n });\n const values: IteratorResult[] = [\n { value: variadicPattern, done: false },\n { done: true, value: undefined },\n ];\n return {\n next: () => values[i++] ?? values.at(-1)!,\n };\n },\n });\n\nfunction arrayChainable>(\n pattern: pattern\n): ArrayChainable {\n return Object.assign(variadic(pattern), {\n optional: () => arrayChainable(optional(pattern)),\n select: (key: any) =>\n arrayChainable(\n key === undefined ? select(pattern) : select(key, pattern)\n ),\n }) as any;\n}\n\n/**\n * `P.optional(subpattern)` takes a sub pattern and returns a pattern which matches if the\n * key is undefined or if it is defined and the sub pattern matches its value.\n *\n * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns)\n *\n * @example\n * match(value)\n * .with({ greeting: P.optional('Hello') }, () => 'will match { greeting?: \"Hello\" }')\n */\nexport function optional<\n input,\n const pattern extends unknown extends input ? UnknownPattern : Pattern\n>(pattern: pattern): Chainable, 'optional'> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n if (value === undefined) {\n getSelectionKeys(pattern).forEach((key) =>\n selector(key, undefined)\n );\n return { matched: true, selections };\n }\n const matched = matchPattern(pattern, value, selector);\n return { matched, selections };\n },\n getSelectionKeys: () => getSelectionKeys(pattern),\n matcherType: 'optional',\n };\n },\n });\n}\n\ntype UnwrapArray = xs extends readonly (infer x)[] ? x : never;\n\ntype UnwrapSet = xs extends Set ? x : never;\n\ntype UnwrapMapKey = xs extends Map ? k : never;\n\ntype UnwrapMapValue = xs extends Map ? v : never;\n\ntype WithDefault = [a] extends [never] ? b : a;\n\n/**\n * `P.array(subpattern)` takes a sub pattern and returns a pattern, which matches\n * arrays if all their elements match the sub pattern.\n *\n * [Read the documentation for `P.array` on GitHub](https://github.com/gvergnaud/ts-pattern#parray-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.array({ name: P.string }) }, () => 'will match { name: string }[]')\n */\nexport function array(): ArrayChainable>;\nexport function array<\n input,\n const pattern extends Pattern, unknown>>\n>(pattern: pattern): ArrayChainable>;\nexport function array(\n ...args: [pattern?: any]\n): ArrayChainable> {\n return arrayChainable({\n [matcher]() {\n return {\n match: (value: any) => {\n if (!Array.isArray(value)) return { matched: false };\n\n if (args.length === 0) return { matched: true };\n\n const pattern = args[0];\n let selections: Record = {};\n\n if (value.length === 0) {\n getSelectionKeys(pattern).forEach((key) => {\n selections[key] = [];\n });\n return { matched: true, selections };\n }\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n const matched = value.every((v) =>\n matchPattern(pattern, v, selector)\n );\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0 ? [] : getSelectionKeys(args[0]),\n };\n },\n });\n}\n\n/**\n * `P.set(subpattern)` takes a sub pattern and returns a pattern that matches\n * sets if all their elements match the sub pattern.\n *\n * [Read `P.set` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pset-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.set(P.string) }, () => 'will match Set')\n */\nexport function set(): Chainable>;\nexport function set<\n input,\n const pattern extends Pattern, unknown>>\n>(pattern: pattern): Chainable>;\nexport function set<\n input,\n const pattern extends Pattern, unknown>>\n>(...args: [pattern?: pattern]): Chainable> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n if (!(value instanceof Set)) return { matched: false };\n\n let selections: Record = {};\n\n if (value.size === 0) {\n return { matched: true, selections };\n }\n\n if (args.length === 0) return { matched: true };\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n const pattern = args[0];\n\n const matched = setEvery(value, (v) =>\n matchPattern(pattern, v, selector)\n );\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0 ? [] : getSelectionKeys(args[0]),\n };\n },\n });\n}\n\nconst setEvery = (set: Set, predicate: (value: T) => boolean) => {\n for (const value of set) {\n if (predicate(value)) continue;\n return false;\n }\n return true;\n};\n\n/**\n * `P.map(keyPattern, valuePattern)` takes a subpattern to match against the\n * key, a subpattern to match against the value and returns a pattern that\n * matches on maps where all elements inside the map match those two\n * subpatterns.\n *\n * [Read `P.map` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pmap-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.map(P.map(P.string, P.number)) }, (map) => `map's type is Map`)\n */\nexport function map(): Chainable>;\nexport function map<\n input,\n const pkey extends Pattern, unknown>>,\n const pvalue extends Pattern, unknown>>\n>(patternKey: pkey, patternValue: pvalue): Chainable>;\nexport function map<\n input,\n const pkey extends Pattern, unknown>>,\n const pvalue extends Pattern, unknown>>\n>(\n ...args: [patternKey?: pkey, patternValue?: pvalue]\n): Chainable> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n if (!(value instanceof Map)) return { matched: false };\n\n let selections: Record = {};\n\n if (value.size === 0) {\n return { matched: true, selections };\n }\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n if (args.length === 0) return { matched: true };\n if (args.length === 1) {\n throw new Error(\n `\\`P.map\\` wasn\\'t given enough arguments. Expected (key, value), received ${args[0]?.toString()}`\n );\n }\n const [patternKey, patternValue] = args;\n\n const matched = mapEvery(value, (v, k) => {\n const keyMatch = matchPattern(patternKey, k, selector);\n const valueMatch = matchPattern(patternValue, v, selector);\n return keyMatch && valueMatch;\n });\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0\n ? []\n : [...getSelectionKeys(args[0]), ...getSelectionKeys(args[1])],\n };\n },\n });\n}\n\nconst mapEvery = (\n map: Map,\n predicate: (value: T, key: K) => boolean\n) => {\n for (const [key, value] of map.entries()) {\n if (predicate(value, key)) continue;\n return false;\n }\n return true;\n};\n\n/**\n * `P.intersection(...patterns)` returns a pattern which matches\n * only if **every** patterns provided in parameter match the input.\n *\n * [Read the documentation for `P.intersection` on GitHub](https://github.com/gvergnaud/ts-pattern#pintersection-patterns)\n *\n * @example\n * match(value)\n * .with(\n * {\n * user: P.intersection(\n * { firstname: P.string },\n * { lastname: P.string },\n * { age: P.when(age => age > 21) }\n * )\n * },\n * ({ user }) => 'will match { firstname: string, lastname: string, age: number } if age > 21'\n * )\n */\nexport function intersection<\n input,\n const patterns extends readonly [Pattern, ...Pattern[]]\n>(...patterns: patterns): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n const matched = (patterns as readonly UnknownPattern[]).every((p) =>\n matchPattern(p, value, selector)\n );\n return { matched, selections };\n },\n getSelectionKeys: () =>\n flatMap(patterns as readonly UnknownPattern[], getSelectionKeys),\n matcherType: 'and',\n }),\n });\n}\n\n/**\n * `P.union(...patterns)` returns a pattern which matches\n * if **at least one** of the patterns provided in parameter match the input.\n *\n * [Read the documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#punion-patterns)\n *\n * @example\n * match(value)\n * .with(\n * { type: P.union('a', 'b', 'c') },\n * ({ type }) => 'will match { type: \"a\" | \"b\" | \"c\" }'\n * )\n */\nexport function union<\n input,\n const patterns extends readonly [Pattern, ...Pattern[]]\n>(...patterns: patterns): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value: UnknownInput | input) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n flatMap(\n patterns as readonly UnknownPattern[],\n getSelectionKeys\n ).forEach((key) => selector(key, undefined));\n const matched = (patterns as readonly UnknownPattern[]).some((p) =>\n matchPattern(p, value, selector)\n );\n return { matched, selections };\n },\n getSelectionKeys: () =>\n flatMap(patterns as readonly UnknownPattern[], getSelectionKeys),\n matcherType: 'or',\n }),\n });\n}\n\n/**\n * `P.not(pattern)` returns a pattern which matches if the sub pattern\n * doesn't match.\n *\n * [Read the documentation for `P.not` on GitHub](https://github.com/gvergnaud/ts-pattern#pnot-patterns)\n *\n * @example\n * match<{ a: string | number }>(value)\n * .with({ a: P.not(P.string) }, (x) => 'will match { a: number }'\n * )\n */\n\nexport function not<\n input,\n const pattern extends Pattern | UnknownPattern\n>(pattern: pattern): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value: UnknownInput | input) => ({\n matched: !matchPattern(pattern, value, () => {}),\n }),\n getSelectionKeys: () => [],\n matcherType: 'not',\n }),\n });\n}\n\n/**\n * `P.when((value) => boolean)` returns a pattern which matches\n * if the predicate returns true for the current input.\n *\n * [Read the documentation for `P.when` on GitHub](https://github.com/gvergnaud/ts-pattern#pwhen-patterns)\n *\n * @example\n * match<{ age: number }>(value)\n * .with({ age: P.when(age => age > 21) }, (x) => 'will match if value.age > 21'\n * )\n */\nexport function when unknown>(\n predicate: predicate\n): GuardP<\n input,\n predicate extends (value: any) => value is infer narrowed ? narrowed : never\n>;\nexport function when(\n predicate: (input: input) => input is narrowed\n): GuardExcludeP;\nexport function when unknown>(\n predicate: predicate\n): GuardP<\n input,\n predicate extends (value: any) => value is infer narrowed ? narrowed : never\n> {\n return {\n [matcher]: () => ({\n match: (value: UnknownInput | input) => ({\n matched: Boolean(predicate(value as input)),\n }),\n }),\n };\n}\n\n/**\n * `P.select()` is a pattern which will always match,\n * and will inject the selected piece of input in the handler function.\n *\n * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns)\n *\n * @example\n * match<{ age: number }>(value)\n * .with({ age: P.select() }, (age) => 'age: number'\n * )\n */\nexport function select(): Chainable;\nexport function select<\n input,\n const patternOrKey extends\n | string\n | (unknown extends input ? UnknownPattern : Pattern)\n>(\n patternOrKey: patternOrKey\n): patternOrKey extends string\n ? Chainable>\n : Chainable<\n SelectP,\n 'select' | 'or' | 'and'\n >;\nexport function select<\n input,\n const pattern extends unknown extends input ? UnknownPattern : Pattern,\n const k extends string\n>(\n key: k,\n pattern: pattern\n): Chainable, 'select' | 'or' | 'and'>;\nexport function select(\n ...args: [keyOrPattern?: unknown | string, pattern?: unknown]\n): Chainable, 'select' | 'or' | 'and'> {\n const key: string | undefined =\n typeof args[0] === 'string' ? args[0] : undefined;\n const pattern: unknown =\n args.length === 2\n ? args[1]\n : typeof args[0] === 'string'\n ? undefined\n : args[0];\n return chainable({\n [matcher]() {\n return {\n match: (value) => {\n let selections: Record = {\n [key ?? symbols.anonymousSelectKey]: value,\n };\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n return {\n matched:\n pattern === undefined\n ? true\n : matchPattern(pattern, value, selector),\n selections: selections,\n };\n },\n getSelectionKeys: () =>\n [key ?? symbols.anonymousSelectKey].concat(\n pattern === undefined ? [] : getSelectionKeys(pattern)\n ),\n };\n },\n });\n}\n\nfunction isUnknown(x: unknown): x is unknown {\n return true;\n}\n\nfunction isNumber(x: T | number): x is number {\n return typeof x === 'number';\n}\n\nfunction isString(x: T | string): x is string {\n return typeof x === 'string';\n}\n\nfunction isBoolean(x: T | boolean): x is boolean {\n return typeof x === 'boolean';\n}\n\nfunction isBigInt(x: T | bigint): x is bigint {\n return typeof x === 'bigint';\n}\n\nfunction isSymbol(x: T | symbol): x is symbol {\n return typeof x === 'symbol';\n}\n\nfunction isNullish(x: T | null | undefined): x is null | undefined {\n return x === null || x === undefined;\n}\n\nfunction isNonNullable(x: unknown): x is {} {\n return x !== null && x !== undefined;\n}\n\ntype AnyConstructor = abstract new (...args: any[]) => any;\n\nfunction isInstanceOf(classConstructor: T) {\n return (val: unknown): val is InstanceType =>\n val instanceof classConstructor;\n}\n\n/**\n * `P.any` is a wildcard pattern, matching **any value**.\n *\n * [Read the documentation for `P.any` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard)\n *\n * @example\n * match(value)\n * .with(P.any, () => 'will always match')\n */\nexport const any: AnyPattern = chainable(when(isUnknown));\n\n/**\n * `P._` is a wildcard pattern, matching **any value**.\n * It's an alias to `P.any`.\n *\n * [Read the documentation for `P._` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard)\n *\n * @example\n * match(value)\n * .with(P._, () => 'will always match')\n */\nexport const _ = any;\n\n/**\n * `P.string.startsWith(start)` is a pattern, matching **strings** starting with `start`.\n *\n * [Read the documentation for `P.string.startsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringstartsWith)\n *\n * @example\n * match(value)\n * .with(P.string.startsWith('A'), () => 'value starts with an A')\n */\n\nconst startsWith = (\n start: start\n): GuardP =>\n when((value) => isString(value) && value.startsWith(start));\n\n/**\n * `P.string.endsWith(end)` is a pattern, matching **strings** ending with `end`.\n *\n * [Read the documentation for `P.string.endsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringendsWith)\n *\n * @example\n * match(value)\n * .with(P.string.endsWith('!'), () => 'value ends with an !')\n */\nconst endsWith = (\n end: end\n): GuardP =>\n when((value) => isString(value) && value.endsWith(end));\n\n/**\n * `P.string.minLength(min)` is a pattern, matching **strings** with at least `min` characters.\n *\n * [Read the documentation for `P.string.minLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringminLength)\n *\n * @example\n * match(value)\n * .with(P.string.minLength(10), () => 'string with more length >= 10')\n */\nconst minLength = (min: min) =>\n when((value) => isString(value) && value.length >= min);\n\n/**\n * `P.string.length(len)` is a pattern, matching **strings** with exactly `len` characters.\n *\n * [Read the documentation for `P.string.length` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringlength)\n *\n * @example\n * match(value)\n * .with(P.string.length(10), () => 'strings with length === 10')\n */\nconst length = (len: len) =>\n when((value) => isString(value) && value.length === len);\n\n/**\n * `P.string.maxLength(max)` is a pattern, matching **strings** with at most `max` characters.\n *\n * [Read the documentation for `P.string.maxLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringmaxLength)\n *\n * @example\n * match(value)\n * .with(P.string.maxLength(10), () => 'string with more length <= 10')\n */\nconst maxLength = (max: max) =>\n when((value) => isString(value) && value.length <= max);\n\n/**\n * `P.string.includes(substr)` is a pattern, matching **strings** containing `substr`.\n *\n * [Read the documentation for `P.string.includes` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringincludes)\n *\n * @example\n * match(value)\n * .with(P.string.includes('http'), () => 'value contains http')\n */\nconst includes = (\n substr: substr\n): GuardExcludeP =>\n when((value) => isString(value) && value.includes(substr));\n\n/**\n * `P.string.regex(expr)` is a pattern, matching **strings** that `expr` regular expression.\n *\n * [Read the documentation for `P.string.regex` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringregex)\n *\n * @example\n * match(value)\n * .with(P.string.regex(/^https?:\\/\\//), () => 'url')\n */\nconst regex = (\n expr: expr\n): GuardExcludeP =>\n when((value) => isString(value) && Boolean(value.match(expr)));\n\nconst stringChainable = >(\n pattern: pattern\n): StringChainable =>\n Object.assign(chainable(pattern), {\n startsWith: (str: string) =>\n stringChainable(intersection(pattern, startsWith(str))),\n endsWith: (str: string) =>\n stringChainable(intersection(pattern, endsWith(str))),\n minLength: (min: number) =>\n stringChainable(intersection(pattern, minLength(min))),\n length: (len: number) =>\n stringChainable(intersection(pattern, length(len))),\n maxLength: (max: number) =>\n stringChainable(intersection(pattern, maxLength(max))),\n includes: (str: string) =>\n stringChainable(intersection(pattern, includes(str))),\n regex: (str: string) => stringChainable(intersection(pattern, regex(str))),\n }) as any;\n\n/**\n * `P.string` is a wildcard pattern, matching any **string**.\n *\n * [Read the documentation for `P.string` on GitHub](https://github.com/gvergnaud/ts-pattern#pstring-wildcard)\n *\n * @example\n * match(value)\n * .with(P.string, () => 'will match on strings')\n */\nexport const string: StringPattern = stringChainable(when(isString));\n\n/**\n * `P.number.between(min, max)` matches **numbers** between `min` and `max`,\n * equal to min or equal to max.\n *\n * [Read the documentation for `P.number.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween)\n *\n * @example\n * match(value)\n * .with(P.number.between(0, 10), () => '0 <= numbers <= 10')\n */\nconst between = (\n min: min,\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && min <= value && max >= value);\n\n/**\n * `P.number.lt(max)` matches **numbers** smaller than `max`.\n *\n * [Read the documentation for `P.number.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt)\n *\n * @example\n * match(value)\n * .with(P.number.lt(10), () => 'numbers < 10')\n */\nconst lt = (\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && value < max);\n\n/**\n * `P.number.gt(min)` matches **numbers** greater than `min`.\n *\n * [Read the documentation for `P.number.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt)\n *\n * @example\n * match(value)\n * .with(P.number.gt(10), () => 'numbers > 10')\n */\nconst gt = (\n min: min\n): GuardExcludeP =>\n when((value) => isNumber(value) && value > min);\n\n/**\n * `P.number.lte(max)` matches **numbers** smaller than or equal to `max`.\n *\n * [Read the documentation for `P.number.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte)\n *\n * @example\n * match(value)\n * .with(P.number.lte(10), () => 'numbers <= 10')\n */\nconst lte = (\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && value <= max);\n\n/**\n * `P.number.gte(min)` matches **numbers** greater than or equal to `min`.\n *\n * [Read the documentation for `P.number.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergte)\n *\n * @example\n * match(value)\n * .with(P.number.gte(10), () => 'numbers >= 10')\n */\nconst gte = (\n min: min\n): GuardExcludeP =>\n when((value) => isNumber(value) && value >= min);\n\n/**\n * `P.number.int()` matches **integer** numbers.\n *\n * [Read the documentation for `P.number.int()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberint)\n *\n * @example\n * match(value)\n * .with(P.number.int(), () => 'an integer')\n */\nconst int = (): GuardExcludeP =>\n when((value) => isNumber(value) && Number.isInteger(value));\n\n/**\n * `P.number.finite` matches **finite numbers**.\n *\n * [Read the documentation for `P.number.finite` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberfinite)\n *\n * @example\n * match(value)\n * .with(P.number.finite, () => 'not Infinity')\n */\nconst finite = (): GuardExcludeP =>\n when((value) => isNumber(value) && Number.isFinite(value));\n\n/**\n * `P.number.positive()` matches **positive** numbers.\n *\n * [Read the documentation for `P.number.positive()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberpositive)\n *\n * @example\n * match(value)\n * .with(P.number.positive(), () => 'number > 0')\n */\nconst positive = (): GuardExcludeP =>\n when((value) => isNumber(value) && value > 0);\n\n/**\n * `P.number.negative()` matches **negative** numbers.\n *\n * [Read the documentation for `P.number.negative()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbernegative)\n *\n * @example\n * match(value)\n * .with(P.number.negative(), () => 'number < 0')\n */\nconst negative = (): GuardExcludeP =>\n when((value) => isNumber(value) && value < 0);\n\nconst numberChainable = >(\n pattern: pattern\n): NumberChainable =>\n Object.assign(chainable(pattern), {\n between: (min: number, max: number) =>\n numberChainable(intersection(pattern, between(min, max))),\n lt: (max: number) => numberChainable(intersection(pattern, lt(max))),\n gt: (min: number) => numberChainable(intersection(pattern, gt(min))),\n lte: (max: number) => numberChainable(intersection(pattern, lte(max))),\n gte: (min: number) => numberChainable(intersection(pattern, gte(min))),\n int: () => numberChainable(intersection(pattern, int())),\n finite: () => numberChainable(intersection(pattern, finite())),\n positive: () => numberChainable(intersection(pattern, positive())),\n negative: () => numberChainable(intersection(pattern, negative())),\n }) as any;\n\n/**\n * `P.number` is a wildcard pattern, matching any **number**.\n *\n * [Read the documentation for `P.number` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumber-wildcard)\n *\n * @example\n * match(value)\n * .with(P.number, () => 'will match on numbers')\n */\nexport const number: NumberPattern = numberChainable(when(isNumber));\n\n/**\n * `P.bigint.between(min, max)` matches **bigint** between `min` and `max`,\n * equal to min or equal to max.\n *\n * [Read the documentation for `P.bigint.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween)\n *\n * @example\n * match(value)\n * .with(P.bigint.between(0, 10), () => '0 <= bigints <= 10')\n */\nconst betweenBigInt = <\n input,\n const min extends bigint,\n const max extends bigint\n>(\n min: min,\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && min <= value && max >= value);\n\n/**\n * `P.bigint.lt(max)` matches **bigint** smaller than `max`.\n *\n * [Read the documentation for `P.bigint.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt)\n *\n * @example\n * match(value)\n * .with(P.bigint.lt(10), () => 'bigints < 10')\n */\nconst ltBigInt = (\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value < max);\n\n/**\n * `P.bigint.gt(min)` matches **bigint** greater than `min`.\n *\n * [Read the documentation for `P.bigint.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt)\n *\n * @example\n * match(value)\n * .with(P.bigint.gt(10), () => 'bigints > 10')\n */\nconst gtBigInt = (\n min: min\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value > min);\n\n/**\n * `P.bigint.lte(max)` matches **bigint** smaller than or equal to `max`.\n *\n * [Read the documentation for `P.bigint.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte)\n *\n * @example\n * match(value)\n * .with(P.bigint.lte(10), () => 'bigints <= 10')\n */\nconst lteBigInt = (\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value <= max);\n\n/**\n * `P.bigint.gte(min)` matches **bigint** greater than or equal to `min`.\n *\n * [Read the documentation for `P.bigint.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintgte)\n *\n * @example\n * match(value)\n * .with(P.bigint.gte(10), () => 'bigints >= 10')\n */\nconst gteBigInt = (\n min: min\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value >= min);\n\n/**\n * `P.bigint.positive()` matches **positive** bigints.\n *\n * [Read the documentation for `P.bigint.positive()` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintpositive)\n *\n * @example\n * match(value)\n * .with(P.bigint.positive(), () => 'bigint > 0')\n */\nconst positiveBigInt = (): GuardExcludeP =>\n when((value) => isBigInt(value) && value > 0);\n\n/**\n * `P.bigint.negative()` matches **negative** bigints.\n *\n * [Read the documentation for `P.bigint.negative()` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintnegative)\n *\n * @example\n * match(value)\n * .with(P.bigint.negative(), () => 'bigint < 0')\n */\nconst negativeBigInt = (): GuardExcludeP =>\n when((value) => isBigInt(value) && value < 0);\n\nconst bigintChainable = >(\n pattern: pattern\n): BigIntChainable =>\n Object.assign(chainable(pattern), {\n between: (min: bigint, max: bigint) =>\n bigintChainable(intersection(pattern, betweenBigInt(min, max))),\n lt: (max: bigint) => bigintChainable(intersection(pattern, ltBigInt(max))),\n gt: (min: bigint) => bigintChainable(intersection(pattern, gtBigInt(min))),\n lte: (max: bigint) =>\n bigintChainable(intersection(pattern, lteBigInt(max))),\n gte: (min: bigint) =>\n bigintChainable(intersection(pattern, gteBigInt(min))),\n positive: () => bigintChainable(intersection(pattern, positiveBigInt())),\n negative: () => bigintChainable(intersection(pattern, negativeBigInt())),\n }) as any;\n\n/**\n * `P.bigint` is a wildcard pattern, matching any **bigint**.\n *\n * [Read the documentation for `P.bigint` on GitHub](https://github.com/gvergnaud/ts-pattern#number-wildcard)\n *\n * @example\n * .with(P.bigint, () => 'will match on bigints')\n */\nexport const bigint: BigIntPattern = bigintChainable(when(isBigInt));\n\n/**\n * `P.boolean` is a wildcard pattern, matching any **boolean**.\n *\n * [Read the documentation for `P.boolean` on GitHub](https://github.com/gvergnaud/ts-pattern#boolean-wildcard)\n *\n * @example\n * .with(P.boolean, () => 'will match on booleans')\n */\nexport const boolean: BooleanPattern = chainable(when(isBoolean));\n\n/**\n * `P.symbol` is a wildcard pattern, matching any **symbol**.\n *\n * [Read the documentation for `P.symbol` on GitHub](https://github.com/gvergnaud/ts-pattern#symbol-wildcard)\n *\n * @example\n * .with(P.symbol, () => 'will match on symbols')\n */\nexport const symbol: SymbolPattern = chainable(when(isSymbol));\n\n/**\n * `P.nullish` is a wildcard pattern, matching **null** or **undefined**.\n *\n * [Read the documentation for `P.nullish` on GitHub](https://github.com/gvergnaud/ts-pattern#nullish-wildcard)\n *\n * @example\n * .with(P.nullish, (x) => `${x} is null or undefined`)\n */\nexport const nullish: NullishPattern = chainable(when(isNullish));\n\n/**\n * `P.nonNullable` is a wildcard pattern, matching everything except **null** or **undefined**.\n *\n * [Read the documentation for `P.nonNullable` on GitHub](https://github.com/gvergnaud/ts-pattern#nonNullable-wildcard)\n *\n * @example\n * .with(P.nonNullable, (x) => `${x} isn't null nor undefined`)\n */\nexport const nonNullable: NonNullablePattern = chainable(when(isNonNullable));\n\n/**\n * `P.instanceOf(SomeClass)` is a pattern matching instances of a given class.\n *\n * [Read the documentation for `P.instanceOf` on GitHub](https://github.com/gvergnaud/ts-pattern#pinstanceof-patterns)\n *\n * @example\n * .with(P.instanceOf(SomeClass), () => 'will match on SomeClass instances')\n */\nexport function instanceOf(\n classConstructor: T\n): Chainable>> {\n return chainable(when(isInstanceOf(classConstructor)));\n}\n\n/**\n * `P.shape(somePattern)` lets you call methods like `.optional()`, `.and`, `.or` and `.select()`\n * On structural patterns, like objects and arrays.\n *\n * [Read the documentation for `P.shape` on GitHub](https://github.com/gvergnaud/ts-pattern#pshape-patterns)\n *\n * @example\n * .with(\n * {\n * state: P.shape({ status: \"success\" }).optional().select()\n * },\n * (state) => 'match the success state, or undefined.'\n * )\n */\nexport function shape>(\n pattern: pattern\n): Chainable>>;\nexport function shape(pattern: UnknownPattern) {\n return chainable(when(isMatching(pattern)));\n}\n","/**\n * Error when the given input value does not match any included pattern\n * and .exhaustive() was specified\n */\nexport class NonExhaustiveError extends Error {\n constructor(public input: unknown) {\n let displayedValue;\n try {\n displayedValue = JSON.stringify(input);\n } catch (e) {\n displayedValue = input;\n }\n super(`Pattern matching error: no pattern matches value ${displayedValue}`);\n }\n}\n","import { Pattern } from './types/Pattern';\nimport { Match } from './types/Match';\nimport * as symbols from './internals/symbols';\nimport { matchPattern } from './internals/helpers';\nimport { NonExhaustiveError } from './errors';\n\ntype MatchState =\n | { matched: true; value: output }\n | { matched: false; value: undefined };\n\nconst unmatched: MatchState = {\n matched: false,\n value: undefined,\n};\n\n/**\n * `match` creates a **pattern matching expression**.\n * * Use `.with(pattern, handler)` to pattern match on the input.\n * * Use `.exhaustive()` or `.otherwise(() => defaultValue)` to end the expression and get the result.\n *\n * [Read the documentation for `match` on GitHub](https://github.com/gvergnaud/ts-pattern#match)\n *\n * @example\n * declare let input: \"A\" | \"B\";\n *\n * return match(input)\n * .with(\"A\", () => \"It's an A!\")\n * .with(\"B\", () => \"It's a B!\")\n * .exhaustive();\n *\n */\nexport function match(\n value: input\n): Match {\n return new MatchExpression(value, unmatched) as any;\n}\n\n/**\n * This class represents a match expression. It follows the\n * builder pattern, we chain methods to add features to the expression\n * until we call `.exhaustive`, `.otherwise` or the unsafe `.run`\n * method to execute it.\n *\n * The types of this class aren't public, the public type definition\n * can be found in src/types/Match.ts.\n */\nclass MatchExpression {\n constructor(private input: input, private state: MatchState) {}\n\n with(...args: any[]): MatchExpression {\n if (this.state.matched) return this;\n\n const handler: (selection: unknown, value: input) => output =\n args[args.length - 1];\n\n const patterns: Pattern[] = [args[0]];\n let predicate: ((value: input) => unknown) | undefined = undefined;\n\n if (args.length === 3 && typeof args[1] === 'function') {\n // case with guard as second argument\n predicate = args[1];\n } else if (args.length > 2) {\n // case with several patterns\n patterns.push(...args.slice(1, args.length - 1));\n }\n\n let hasSelections = false;\n let selected: Record = {};\n const select = (key: string, value: unknown) => {\n hasSelections = true;\n selected[key] = value;\n };\n\n const matched =\n patterns.some((pattern) => matchPattern(pattern, this.input, select)) &&\n (predicate ? Boolean(predicate(this.input)) : true);\n\n const selections = hasSelections\n ? symbols.anonymousSelectKey in selected\n ? selected[symbols.anonymousSelectKey]\n : selected\n : this.input;\n\n const state = matched\n ? {\n matched: true as const,\n value: handler(selections, this.input),\n }\n : unmatched;\n\n return new MatchExpression(this.input, state);\n }\n\n when(\n predicate: (value: input) => unknown,\n handler: (selection: input, value: input) => output\n ): MatchExpression {\n if (this.state.matched) return this;\n\n const matched = Boolean(predicate(this.input));\n\n return new MatchExpression(\n this.input,\n matched\n ? { matched: true, value: handler(this.input, this.input) }\n : unmatched\n );\n }\n\n otherwise(handler: (value: input) => output): output {\n if (this.state.matched) return this.state.value;\n return handler(this.input);\n }\n\n exhaustive(): output {\n if (this.state.matched) return this.state.value;\n\n throw new NonExhaustiveError(this.input);\n }\n\n run(): output {\n return this.exhaustive();\n }\n\n returnType() {\n return this;\n }\n}\n"],"names":["matcher","Symbol","isVariadic","anonymousSelectKey","isObject","value","Boolean","isMatcher","x","symbols","matchPattern","pattern","select","_matcher$match","match","matched","selections","Object","keys","forEach","key","Array","isArray","_step","startPatterns","endPatterns","variadicPatterns","_iterator","_createForOfIteratorHelperLoose","done","subpattern","push","length","Error","startValues","slice","endValues","middleValues","Infinity","every","subPattern","i","Reflect","ownKeys","k","matcherType","is","getSelectionKeys","_pattern$symbols$matc","_pattern$symbols$matc2","_pattern$symbols$matc3","call","flatMap","values","xs","f","reduce","acc","concat","isMatching","args","arguments","chainable","assign","optional","and","p2","intersection","or","union","undefined","arrayChainable","_Object$assign2","iterator","_Object$assign","next","_values$i","at","variadic","_chainable","selector","setEvery","set","predicate","mapEvery","map","_step2","_iterator2","entries","_step2$value","_chainable4","patterns","p","_chainable5","some","when","_ref","_chainable7","_selections","isNumber","isString","isBigInt","any","_","string","stringChainable","startsWith","str","start","endsWith","end","minLength","min","len","maxLength","max","includes","substr","regex","expr","number","numberChainable","between","lt","gt","lte","gte","int","Number","isInteger","finite","isFinite","positive","negative","bigint","bigintChainable","betweenBigInt","ltBigInt","gtBigInt","lteBigInt","gteBigInt","boolean","symbol","nullish","nonNullable","_arrayChainable","v","_chainable2","Set","size","_chainable3","Map","_args$","toString","patternKey","patternValue","keyMatch","valueMatch","_chainable6","classConstructor","val","isInstanceOf","NonExhaustiveError","_Error","input","_this","displayedValue","JSON","stringify","e","this","_wrapNativeSuper","unmatched","MatchExpression","state","_proto","prototype","handler","apply","hasSelections","selected","otherwise","exhaustive","run","returnType"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.cts b/dist/index.d.cts new file mode 100644 index 00000000..20238150 --- /dev/null +++ b/dist/index.d.cts @@ -0,0 +1,5 @@ +import * as Pattern from './patterns.cjs'; +export { match } from './match.cjs'; +export { isMatching } from './is-matching.cjs'; +export { Pattern, Pattern as P }; +export { NonExhaustiveError } from './errors.cjs'; diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 00000000..a15287c7 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,5 @@ +import * as Pattern from './patterns.js'; +export { match } from './match.js'; +export { isMatching } from './is-matching.js'; +export { Pattern, Pattern as P }; +export { NonExhaustiveError } from './errors.js'; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 00000000..ec024560 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,2 @@ +const t=Symbol.for("@ts-pattern/matcher"),e=Symbol.for("@ts-pattern/isVariadic"),n="@ts-pattern/anonymous-select-key",r=t=>Boolean(t&&"object"==typeof t),i=e=>e&&!!e[t],s=(n,o,c)=>{if(i(n)){const e=n[t](),{matched:r,selections:i}=e.match(o);return r&&i&&Object.keys(i).forEach(t=>c(t,i[t])),r}if(r(n)){if(!r(o))return!1;if(Array.isArray(n)){if(!Array.isArray(o))return!1;let t=[],r=[],a=[];for(const s of n.keys()){const o=n[s];i(o)&&o[e]?a.push(o):a.length?r.push(o):t.push(o)}if(a.length){if(a.length>1)throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(o.lengths(t,e[n],c))&&r.every((t,e)=>s(t,n[e],c))&&(0===a.length||s(a[0],i,c))}return n.length===o.length&&n.every((t,e)=>s(t,o[e],c))}return Reflect.ownKeys(n).every(e=>{const r=n[e];return(e in o||i(a=r)&&"optional"===a[t]().matcherType)&&s(r,o[e],c);var a})}return Object.is(o,n)},o=e=>{var n,s,a;return r(e)?i(e)?null!=(n=null==(s=(a=e[t]()).getSelectionKeys)?void 0:s.call(a))?n:[]:Array.isArray(e)?c(e,o):c(Object.values(e),o):[]},c=(t,e)=>t.reduce((t,n)=>t.concat(e(n)),[]);function a(...t){if(1===t.length){const[e]=t;return t=>s(e,t,()=>{})}if(2===t.length){const[e,n]=t;return s(e,n,()=>{})}throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t.length}.`)}function u(t){return Object.assign(t,{optional:()=>h(t),and:e=>m(t,e),or:e=>d(t,e),select:e=>void 0===e?y(t):y(e,t)})}function l(t){return Object.assign((t=>Object.assign(t,{[Symbol.iterator](){let n=0;const r=[{value:Object.assign(t,{[e]:!0}),done:!1},{done:!0,value:void 0}];return{next:()=>{var t;return null!=(t=r[n++])?t:r.at(-1)}}}}))(t),{optional:()=>l(h(t)),select:e=>l(void 0===e?y(t):y(e,t))})}function h(e){return u({[t]:()=>({match:t=>{let n={};const r=(t,e)=>{n[t]=e};return void 0===t?(o(e).forEach(t=>r(t,void 0)),{matched:!0,selections:n}):{matched:s(e,t,r),selections:n}},getSelectionKeys:()=>o(e),matcherType:"optional"})})}const f=(t,e)=>{for(const n of t)if(!e(n))return!1;return!0},g=(t,e)=>{for(const[n,r]of t.entries())if(!e(r,n))return!1;return!0};function m(...e){return u({[t]:()=>({match:t=>{let n={};const r=(t,e)=>{n[t]=e};return{matched:e.every(e=>s(e,t,r)),selections:n}},getSelectionKeys:()=>c(e,o),matcherType:"and"})})}function d(...e){return u({[t]:()=>({match:t=>{let n={};const r=(t,e)=>{n[t]=e};return c(e,o).forEach(t=>r(t,void 0)),{matched:e.some(e=>s(e,t,r)),selections:n}},getSelectionKeys:()=>c(e,o),matcherType:"or"})})}function p(e){return{[t]:()=>({match:t=>({matched:Boolean(e(t))})})}}function y(...e){const r="string"==typeof e[0]?e[0]:void 0,i=2===e.length?e[1]:"string"==typeof e[0]?void 0:e[0];return u({[t]:()=>({match:t=>{let e={[null!=r?r:n]:t};return{matched:void 0===i||s(i,t,(t,n)=>{e[t]=n}),selections:e}},getSelectionKeys:()=>[null!=r?r:n].concat(void 0===i?[]:o(i))})})}function v(t){return"number"==typeof t}function b(t){return"string"==typeof t}function w(t){return"bigint"==typeof t}const S=u(p(function(t){return!0})),O=S,j=t=>Object.assign(u(t),{startsWith:e=>{return j(m(t,(n=e,p(t=>b(t)&&t.startsWith(n)))));var n},endsWith:e=>{return j(m(t,(n=e,p(t=>b(t)&&t.endsWith(n)))));var n},minLength:e=>j(m(t,(t=>p(e=>b(e)&&e.length>=t))(e))),length:e=>j(m(t,(t=>p(e=>b(e)&&e.length===t))(e))),maxLength:e=>j(m(t,(t=>p(e=>b(e)&&e.length<=t))(e))),includes:e=>{return j(m(t,(n=e,p(t=>b(t)&&t.includes(n)))));var n},regex:e=>{return j(m(t,(n=e,p(t=>b(t)&&Boolean(t.match(n))))));var n}}),K=j(p(b)),x=t=>Object.assign(u(t),{between:(e,n)=>x(m(t,((t,e)=>p(n=>v(n)&&t<=n&&e>=n))(e,n))),lt:e=>x(m(t,(t=>p(e=>v(e)&&ex(m(t,(t=>p(e=>v(e)&&e>t))(e))),lte:e=>x(m(t,(t=>p(e=>v(e)&&e<=t))(e))),gte:e=>x(m(t,(t=>p(e=>v(e)&&e>=t))(e))),int:()=>x(m(t,p(t=>v(t)&&Number.isInteger(t)))),finite:()=>x(m(t,p(t=>v(t)&&Number.isFinite(t)))),positive:()=>x(m(t,p(t=>v(t)&&t>0))),negative:()=>x(m(t,p(t=>v(t)&&t<0)))}),E=x(p(v)),A=t=>Object.assign(u(t),{between:(e,n)=>A(m(t,((t,e)=>p(n=>w(n)&&t<=n&&e>=n))(e,n))),lt:e=>A(m(t,(t=>p(e=>w(e)&&eA(m(t,(t=>p(e=>w(e)&&e>t))(e))),lte:e=>A(m(t,(t=>p(e=>w(e)&&e<=t))(e))),gte:e=>A(m(t,(t=>p(e=>w(e)&&e>=t))(e))),positive:()=>A(m(t,p(t=>w(t)&&t>0))),negative:()=>A(m(t,p(t=>w(t)&&t<0)))}),P=A(p(w)),T=u(p(function(t){return"boolean"==typeof t})),B=u(p(function(t){return"symbol"==typeof t})),_=u(p(function(t){return null==t})),k=u(p(function(t){return null!=t}));var N={__proto__:null,matcher:t,optional:h,array:function(...e){return l({[t]:()=>({match:t=>{if(!Array.isArray(t))return{matched:!1};if(0===e.length)return{matched:!0};const n=e[0];let r={};if(0===t.length)return o(n).forEach(t=>{r[t]=[]}),{matched:!0,selections:r};const i=(t,e)=>{r[t]=(r[t]||[]).concat([e])};return{matched:t.every(t=>s(n,t,i)),selections:r}},getSelectionKeys:()=>0===e.length?[]:o(e[0])})})},set:function(...e){return u({[t]:()=>({match:t=>{if(!(t instanceof Set))return{matched:!1};let n={};if(0===t.size)return{matched:!0,selections:n};if(0===e.length)return{matched:!0};const r=(t,e)=>{n[t]=(n[t]||[]).concat([e])},i=e[0];return{matched:f(t,t=>s(i,t,r)),selections:n}},getSelectionKeys:()=>0===e.length?[]:o(e[0])})})},map:function(...e){return u({[t]:()=>({match:t=>{if(!(t instanceof Map))return{matched:!1};let n={};if(0===t.size)return{matched:!0,selections:n};const r=(t,e)=>{n[t]=(n[t]||[]).concat([e])};if(0===e.length)return{matched:!0};var i;if(1===e.length)throw new Error(`\`P.map\` wasn't given enough arguments. Expected (key, value), received ${null==(i=e[0])?void 0:i.toString()}`);const[o,c]=e;return{matched:g(t,(t,e)=>{const n=s(o,e,r),i=s(c,t,r);return n&&i}),selections:n}},getSelectionKeys:()=>0===e.length?[]:[...o(e[0]),...o(e[1])]})})},intersection:m,union:d,not:function(e){return u({[t]:()=>({match:t=>({matched:!s(e,t,()=>{})}),getSelectionKeys:()=>[],matcherType:"not"})})},when:p,select:y,any:S,_:O,string:K,number:E,bigint:P,boolean:T,symbol:B,nullish:_,nonNullable:k,instanceOf:function(t){return u(p(function(t){return e=>e instanceof t}(t)))},shape:function(t){return u(p(a(t)))}};class W extends Error{constructor(t){let e;try{e=JSON.stringify(t)}catch(n){e=t}super(`Pattern matching error: no pattern matches value ${e}`),this.input=void 0,this.input=t}}const $={matched:!1,value:void 0};function z(t){return new I(t,$)}class I{constructor(t,e){this.input=void 0,this.state=void 0,this.input=t,this.state=e}with(...t){if(this.state.matched)return this;const e=t[t.length-1],r=[t[0]];let i;3===t.length&&"function"==typeof t[1]?i=t[1]:t.length>2&&r.push(...t.slice(1,t.length-1));let o=!1,c={};const a=(t,e)=>{o=!0,c[t]=e},u=!r.some(t=>s(t,this.input,a))||i&&!Boolean(i(this.input))?$:{matched:!0,value:e(o?n in c?c[n]:c:this.input,this.input)};return new I(this.input,u)}when(t,e){if(this.state.matched)return this;const n=Boolean(t(this.input));return new I(this.input,n?{matched:!0,value:e(this.input,this.input)}:$)}otherwise(t){return this.state.matched?this.state.value:t(this.input)}exhaustive(){if(this.state.matched)return this.state.value;throw new W(this.input)}run(){return this.exhaustive()}returnType(){return this}}export{W as NonExhaustiveError,N as P,N as Pattern,a as isMatching,z as match}; +//# sourceMappingURL=index.js.map diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 00000000..164f7c19 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../src/internals/symbols.ts","../src/internals/helpers.ts","../src/is-matching.ts","../src/patterns.ts","../src/errors.ts","../src/match.ts"],"sourcesContent":["/**\n * Symbols used internally within ts-pattern to construct and discriminate\n * Guard, Not, and Select, and AnonymousSelect patterns\n *\n * Symbols have the advantage of not appearing in auto-complete suggestions in\n * user defined patterns, and eliminate the risk of property\n * overlap between ts-pattern internals and user defined patterns.\n *\n * These symbols have to be visible to tsc for type inference to work, but\n * users should not import them\n * @module\n * @private\n * @internal\n */\n\nexport const matcher = Symbol.for('@ts-pattern/matcher');\nexport type matcher = typeof matcher;\n\nexport const unset = Symbol.for('@ts-pattern/unset');\nexport type unset = typeof unset;\n\nexport const isVariadic = Symbol.for('@ts-pattern/isVariadic');\nexport type isVariadic = typeof isVariadic;\n\n// can't be a symbol because this key has to be enumerable.\nexport const anonymousSelectKey = '@ts-pattern/anonymous-select-key';\nexport type anonymousSelectKey = typeof anonymousSelectKey;\n\nexport const override = Symbol.for('@ts-pattern/override');\nexport type override = typeof override;\n","/**\n * @module\n * @private\n * @internal\n */\n\nimport * as symbols from './symbols';\nimport { SelectionType } from '../types/FindSelected';\nimport { Pattern, Matcher, MatcherType, AnyMatcher } from '../types/Pattern';\n\n// @internal\nexport const isObject = (value: unknown): value is Object =>\n Boolean(value && typeof value === 'object');\n\n// @internal\nexport const isMatcher = (\n x: unknown\n): x is Matcher => {\n const pattern = x as Matcher;\n return pattern && !!pattern[symbols.matcher];\n};\n\n// @internal\nconst isOptionalPattern = (\n x: unknown\n): x is Matcher => {\n return isMatcher(x) && x[symbols.matcher]().matcherType === 'optional';\n};\n\n// tells us if the value matches a given pattern.\n// @internal\nexport const matchPattern = (\n pattern: any,\n value: any,\n select: (key: string, value: unknown) => void\n): boolean => {\n if (isMatcher(pattern)) {\n const matcher = pattern[symbols.matcher]();\n const { matched, selections } = matcher.match(value);\n if (matched && selections) {\n Object.keys(selections).forEach((key) => select(key, selections[key]));\n }\n return matched;\n }\n\n if (isObject(pattern)) {\n if (!isObject(value)) return false;\n\n // Tuple pattern\n if (Array.isArray(pattern)) {\n if (!Array.isArray(value)) return false;\n let startPatterns = [];\n let endPatterns = [];\n let variadicPatterns: AnyMatcher[] = [];\n\n for (const i of pattern.keys()) {\n const subpattern = pattern[i];\n if (isMatcher(subpattern) && subpattern[symbols.isVariadic]) {\n variadicPatterns.push(subpattern);\n } else if (variadicPatterns.length) {\n endPatterns.push(subpattern);\n } else {\n startPatterns.push(subpattern);\n }\n }\n\n if (variadicPatterns.length) {\n if (variadicPatterns.length > 1) {\n throw new Error(\n `Pattern error: Using \\`...P.array(...)\\` several times in a single pattern is not allowed.`\n );\n }\n\n if (value.length < startPatterns.length + endPatterns.length) {\n return false;\n }\n\n const startValues = value.slice(0, startPatterns.length);\n const endValues =\n endPatterns.length === 0 ? [] : value.slice(-endPatterns.length);\n const middleValues = value.slice(\n startPatterns.length,\n endPatterns.length === 0 ? Infinity : -endPatterns.length\n );\n\n return (\n startPatterns.every((subPattern, i) =>\n matchPattern(subPattern, startValues[i], select)\n ) &&\n endPatterns.every((subPattern, i) =>\n matchPattern(subPattern, endValues[i], select)\n ) &&\n (variadicPatterns.length === 0\n ? true\n : matchPattern(variadicPatterns[0], middleValues, select))\n );\n }\n\n return pattern.length === value.length\n ? pattern.every((subPattern, i) =>\n matchPattern(subPattern, value[i], select)\n )\n : false;\n }\n\n return Reflect.ownKeys(pattern).every((k): boolean => {\n const subPattern = pattern[k];\n\n return (\n (k in value || isOptionalPattern(subPattern)) &&\n matchPattern(subPattern, value[k], select)\n );\n });\n }\n\n return Object.is(value, pattern);\n};\n\n// @internal\nexport const getSelectionKeys = (pattern: any): string[] => {\n if (isObject(pattern)) {\n if (isMatcher(pattern)) {\n return pattern[symbols.matcher]().getSelectionKeys?.() ?? [];\n }\n if (Array.isArray(pattern)) return flatMap(pattern, getSelectionKeys);\n return flatMap(Object.values(pattern), getSelectionKeys);\n }\n return [];\n};\n\n// @internal\nexport const flatMap = (\n xs: readonly a[],\n f: (v: a) => readonly b[]\n): b[] => xs.reduce((acc, x) => acc.concat(f(x)), []);\n","import { MatchedValue, Pattern } from './types/Pattern';\nimport * as P from './patterns';\nimport { matchPattern } from './internals/helpers';\n\n/**\n * `isMatching` takes pattern and returns a **type guard** function, cheching if a value matches this pattern.\n *\n * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching)\n *\n * @example\n * const hasName = isMatching({ name: P.string })\n *\n * declare let input: unknown\n *\n * if (hasName(input)) {\n * // `input` inferred as { name: string }\n * return input.name\n * }\n */\nexport function isMatching>(\n pattern: p\n): (value: unknown) => value is P.infer

;\n/**\n * `isMatching` takes pattern and a value and checks if the value matches this pattern.\n *\n * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching)\n *\n * @example\n * declare let input: unknown\n *\n * if (isMatching({ name: P.string }, input)) {\n * // `input` inferred as { name: string }\n * return input.name\n * }\n */\nexport function isMatching>(\n pattern: p,\n value: unknown\n): value is P.infer

;\n\nexport function isMatching>(\n ...args: [pattern: p, value?: any]\n): boolean | ((vale: any) => boolean) {\n if (args.length === 1) {\n const [pattern] = args;\n return (value: any): value is MatchedValue> =>\n matchPattern(pattern, value, () => {});\n }\n if (args.length === 2) {\n const [pattern, value] = args;\n return matchPattern(pattern, value, () => {});\n }\n\n throw new Error(\n `isMatching wasn't given the right number of arguments: expected 1 or 2, received ${args.length}.`\n );\n}\n","import { matchPattern, getSelectionKeys, flatMap } from './internals/helpers';\nimport * as symbols from './internals/symbols';\nimport { matcher } from './internals/symbols';\nimport { isMatching } from './is-matching';\nimport { ExtractPreciseValue } from './types/ExtractPreciseValue';\nimport { Fn } from './types/helpers';\nimport { InvertPattern } from './types/InvertPattern';\nimport {\n Pattern,\n UnknownPattern,\n OptionalP,\n ArrayP,\n MapP,\n SetP,\n AndP,\n OrP,\n NotP,\n GuardP,\n SelectP,\n AnonymousSelectP,\n GuardExcludeP,\n CustomP,\n Matcher,\n StringPattern,\n AnyPattern,\n NumberPattern,\n BooleanPattern,\n BigIntPattern,\n NullishPattern,\n SymbolPattern,\n Chainable,\n BigIntChainable,\n NumberChainable,\n StringChainable,\n ArrayChainable,\n Variadic,\n NonNullablePattern,\n} from './types/Pattern';\n\nexport type { Pattern, Fn as unstable_Fn };\n\nexport { matcher };\n\n/**\n * @experimental\n * A `Matchable` is an object implementing\n * the Matcher Protocol. It must have a `[P.matcher]: P.Matcher`\n * key, which defines how this object should be matched by TS-Pattern.\n *\n * Note that this api is unstable.\n *\n * @example\n * ```ts\n * class Some implements P.unstable_Matchable {\n * [P.matcher](): P.unstable_Matcher>\n * }\n * ```\n */\nexport type unstable_Matchable<\n narrowedOrFn,\n input = unknown,\n pattern = never\n> = CustomP;\n\n/**\n * @experimental\n * A `Matcher` is an object with `match` function, which\n * defines how this object should be matched by TS-Pattern.\n *\n * Note that this api is unstable.\n *\n * @example\n * ```ts\n * class Some implements P.unstable_Matchable {\n * [P.matcher](): P.unstable_Matcher>\n * }\n * ```\n */\nexport type unstable_Matcher<\n narrowedOrFn,\n input = unknown,\n pattern = never\n> = ReturnType[matcher]>;\n\n/**\n * `P.infer` will return the type of the value\n * matched by this pattern.\n *\n * [Read the documentation for `P.infer` on GitHub](https://github.com/gvergnaud/ts-pattern#pinfer)\n *\n * @example\n * const userPattern = { name: P.string }\n * type User = P.infer\n */\nexport type infer> = InvertPattern<\n pattern,\n unknown\n>;\n\n/**\n * `P.narrow` will narrow the input type to only keep\n * the set of values that are compatible with the provided pattern type.\n *\n * [Read the documentation for `P.narrow` on GitHub](https://github.com/gvergnaud/ts-pattern#pnarrow)\n *\n * @example\n * type Input = ['a' | 'b' | 'c', 'a' | 'b' | 'c']\n * const Pattern = ['a', P.union('a', 'b')] as const\n *\n * type Narrowed = P.narrow\n * // ^? ['a', 'a' | 'b']\n */\nexport type narrow> = ExtractPreciseValue<\n input,\n InvertPattern\n>;\n\nfunction chainable>(\n pattern: pattern\n): Chainable {\n return Object.assign(pattern, {\n optional: () => optional(pattern),\n and: (p2: any) => intersection(pattern, p2),\n or: (p2: any) => union(pattern, p2),\n select: (key: any) =>\n key === undefined ? select(pattern) : select(key, pattern),\n }) as Chainable;\n}\n\nconst variadic = (pattern: pattern): Variadic =>\n Object.assign(pattern, {\n [Symbol.iterator](): Iterator {\n let i = 0;\n const variadicPattern = Object.assign(pattern, {\n [symbols.isVariadic]: true,\n });\n const values: IteratorResult[] = [\n { value: variadicPattern, done: false },\n { done: true, value: undefined },\n ];\n return {\n next: () => values[i++] ?? values.at(-1)!,\n };\n },\n });\n\nfunction arrayChainable>(\n pattern: pattern\n): ArrayChainable {\n return Object.assign(variadic(pattern), {\n optional: () => arrayChainable(optional(pattern)),\n select: (key: any) =>\n arrayChainable(\n key === undefined ? select(pattern) : select(key, pattern)\n ),\n }) as any;\n}\n\n/**\n * `P.optional(subpattern)` takes a sub pattern and returns a pattern which matches if the\n * key is undefined or if it is defined and the sub pattern matches its value.\n *\n * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns)\n *\n * @example\n * match(value)\n * .with({ greeting: P.optional('Hello') }, () => 'will match { greeting?: \"Hello\" }')\n */\nexport function optional<\n input,\n const pattern extends unknown extends input ? UnknownPattern : Pattern\n>(pattern: pattern): Chainable, 'optional'> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n if (value === undefined) {\n getSelectionKeys(pattern).forEach((key) =>\n selector(key, undefined)\n );\n return { matched: true, selections };\n }\n const matched = matchPattern(pattern, value, selector);\n return { matched, selections };\n },\n getSelectionKeys: () => getSelectionKeys(pattern),\n matcherType: 'optional',\n };\n },\n });\n}\n\ntype UnwrapArray = xs extends readonly (infer x)[] ? x : never;\n\ntype UnwrapSet = xs extends Set ? x : never;\n\ntype UnwrapMapKey = xs extends Map ? k : never;\n\ntype UnwrapMapValue = xs extends Map ? v : never;\n\ntype WithDefault = [a] extends [never] ? b : a;\n\n/**\n * `P.array(subpattern)` takes a sub pattern and returns a pattern, which matches\n * arrays if all their elements match the sub pattern.\n *\n * [Read the documentation for `P.array` on GitHub](https://github.com/gvergnaud/ts-pattern#parray-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.array({ name: P.string }) }, () => 'will match { name: string }[]')\n */\nexport function array(): ArrayChainable>;\nexport function array<\n input,\n const pattern extends Pattern, unknown>>\n>(pattern: pattern): ArrayChainable>;\nexport function array(\n ...args: [pattern?: any]\n): ArrayChainable> {\n return arrayChainable({\n [matcher]() {\n return {\n match: (value: any) => {\n if (!Array.isArray(value)) return { matched: false };\n\n if (args.length === 0) return { matched: true };\n\n const pattern = args[0];\n let selections: Record = {};\n\n if (value.length === 0) {\n getSelectionKeys(pattern).forEach((key) => {\n selections[key] = [];\n });\n return { matched: true, selections };\n }\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n const matched = value.every((v) =>\n matchPattern(pattern, v, selector)\n );\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0 ? [] : getSelectionKeys(args[0]),\n };\n },\n });\n}\n\n/**\n * `P.set(subpattern)` takes a sub pattern and returns a pattern that matches\n * sets if all their elements match the sub pattern.\n *\n * [Read `P.set` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pset-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.set(P.string) }, () => 'will match Set')\n */\nexport function set(): Chainable>;\nexport function set<\n input,\n const pattern extends Pattern, unknown>>\n>(pattern: pattern): Chainable>;\nexport function set<\n input,\n const pattern extends Pattern, unknown>>\n>(...args: [pattern?: pattern]): Chainable> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n if (!(value instanceof Set)) return { matched: false };\n\n let selections: Record = {};\n\n if (value.size === 0) {\n return { matched: true, selections };\n }\n\n if (args.length === 0) return { matched: true };\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n const pattern = args[0];\n\n const matched = setEvery(value, (v) =>\n matchPattern(pattern, v, selector)\n );\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0 ? [] : getSelectionKeys(args[0]),\n };\n },\n });\n}\n\nconst setEvery = (set: Set, predicate: (value: T) => boolean) => {\n for (const value of set) {\n if (predicate(value)) continue;\n return false;\n }\n return true;\n};\n\n/**\n * `P.map(keyPattern, valuePattern)` takes a subpattern to match against the\n * key, a subpattern to match against the value and returns a pattern that\n * matches on maps where all elements inside the map match those two\n * subpatterns.\n *\n * [Read `P.map` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pmap-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.map(P.map(P.string, P.number)) }, (map) => `map's type is Map`)\n */\nexport function map(): Chainable>;\nexport function map<\n input,\n const pkey extends Pattern, unknown>>,\n const pvalue extends Pattern, unknown>>\n>(patternKey: pkey, patternValue: pvalue): Chainable>;\nexport function map<\n input,\n const pkey extends Pattern, unknown>>,\n const pvalue extends Pattern, unknown>>\n>(\n ...args: [patternKey?: pkey, patternValue?: pvalue]\n): Chainable> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n if (!(value instanceof Map)) return { matched: false };\n\n let selections: Record = {};\n\n if (value.size === 0) {\n return { matched: true, selections };\n }\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n if (args.length === 0) return { matched: true };\n if (args.length === 1) {\n throw new Error(\n `\\`P.map\\` wasn\\'t given enough arguments. Expected (key, value), received ${args[0]?.toString()}`\n );\n }\n const [patternKey, patternValue] = args;\n\n const matched = mapEvery(value, (v, k) => {\n const keyMatch = matchPattern(patternKey, k, selector);\n const valueMatch = matchPattern(patternValue, v, selector);\n return keyMatch && valueMatch;\n });\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0\n ? []\n : [...getSelectionKeys(args[0]), ...getSelectionKeys(args[1])],\n };\n },\n });\n}\n\nconst mapEvery = (\n map: Map,\n predicate: (value: T, key: K) => boolean\n) => {\n for (const [key, value] of map.entries()) {\n if (predicate(value, key)) continue;\n return false;\n }\n return true;\n};\n\n/**\n * `P.intersection(...patterns)` returns a pattern which matches\n * only if **every** patterns provided in parameter match the input.\n *\n * [Read the documentation for `P.intersection` on GitHub](https://github.com/gvergnaud/ts-pattern#pintersection-patterns)\n *\n * @example\n * match(value)\n * .with(\n * {\n * user: P.intersection(\n * { firstname: P.string },\n * { lastname: P.string },\n * { age: P.when(age => age > 21) }\n * )\n * },\n * ({ user }) => 'will match { firstname: string, lastname: string, age: number } if age > 21'\n * )\n */\nexport function intersection<\n input,\n const patterns extends readonly [Pattern, ...Pattern[]]\n>(...patterns: patterns): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n const matched = (patterns as readonly UnknownPattern[]).every((p) =>\n matchPattern(p, value, selector)\n );\n return { matched, selections };\n },\n getSelectionKeys: () =>\n flatMap(patterns as readonly UnknownPattern[], getSelectionKeys),\n matcherType: 'and',\n }),\n });\n}\n\n/**\n * `P.union(...patterns)` returns a pattern which matches\n * if **at least one** of the patterns provided in parameter match the input.\n *\n * [Read the documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#punion-patterns)\n *\n * @example\n * match(value)\n * .with(\n * { type: P.union('a', 'b', 'c') },\n * ({ type }) => 'will match { type: \"a\" | \"b\" | \"c\" }'\n * )\n */\nexport function union<\n input,\n const patterns extends readonly [Pattern, ...Pattern[]]\n>(...patterns: patterns): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value: UnknownInput | input) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n flatMap(\n patterns as readonly UnknownPattern[],\n getSelectionKeys\n ).forEach((key) => selector(key, undefined));\n const matched = (patterns as readonly UnknownPattern[]).some((p) =>\n matchPattern(p, value, selector)\n );\n return { matched, selections };\n },\n getSelectionKeys: () =>\n flatMap(patterns as readonly UnknownPattern[], getSelectionKeys),\n matcherType: 'or',\n }),\n });\n}\n\n/**\n * `P.not(pattern)` returns a pattern which matches if the sub pattern\n * doesn't match.\n *\n * [Read the documentation for `P.not` on GitHub](https://github.com/gvergnaud/ts-pattern#pnot-patterns)\n *\n * @example\n * match<{ a: string | number }>(value)\n * .with({ a: P.not(P.string) }, (x) => 'will match { a: number }'\n * )\n */\n\nexport function not<\n input,\n const pattern extends Pattern | UnknownPattern\n>(pattern: pattern): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value: UnknownInput | input) => ({\n matched: !matchPattern(pattern, value, () => {}),\n }),\n getSelectionKeys: () => [],\n matcherType: 'not',\n }),\n });\n}\n\n/**\n * `P.when((value) => boolean)` returns a pattern which matches\n * if the predicate returns true for the current input.\n *\n * [Read the documentation for `P.when` on GitHub](https://github.com/gvergnaud/ts-pattern#pwhen-patterns)\n *\n * @example\n * match<{ age: number }>(value)\n * .with({ age: P.when(age => age > 21) }, (x) => 'will match if value.age > 21'\n * )\n */\nexport function when unknown>(\n predicate: predicate\n): GuardP<\n input,\n predicate extends (value: any) => value is infer narrowed ? narrowed : never\n>;\nexport function when(\n predicate: (input: input) => input is narrowed\n): GuardExcludeP;\nexport function when unknown>(\n predicate: predicate\n): GuardP<\n input,\n predicate extends (value: any) => value is infer narrowed ? narrowed : never\n> {\n return {\n [matcher]: () => ({\n match: (value: UnknownInput | input) => ({\n matched: Boolean(predicate(value as input)),\n }),\n }),\n };\n}\n\n/**\n * `P.select()` is a pattern which will always match,\n * and will inject the selected piece of input in the handler function.\n *\n * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns)\n *\n * @example\n * match<{ age: number }>(value)\n * .with({ age: P.select() }, (age) => 'age: number'\n * )\n */\nexport function select(): Chainable;\nexport function select<\n input,\n const patternOrKey extends\n | string\n | (unknown extends input ? UnknownPattern : Pattern)\n>(\n patternOrKey: patternOrKey\n): patternOrKey extends string\n ? Chainable>\n : Chainable<\n SelectP,\n 'select' | 'or' | 'and'\n >;\nexport function select<\n input,\n const pattern extends unknown extends input ? UnknownPattern : Pattern,\n const k extends string\n>(\n key: k,\n pattern: pattern\n): Chainable, 'select' | 'or' | 'and'>;\nexport function select(\n ...args: [keyOrPattern?: unknown | string, pattern?: unknown]\n): Chainable, 'select' | 'or' | 'and'> {\n const key: string | undefined =\n typeof args[0] === 'string' ? args[0] : undefined;\n const pattern: unknown =\n args.length === 2\n ? args[1]\n : typeof args[0] === 'string'\n ? undefined\n : args[0];\n return chainable({\n [matcher]() {\n return {\n match: (value) => {\n let selections: Record = {\n [key ?? symbols.anonymousSelectKey]: value,\n };\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n return {\n matched:\n pattern === undefined\n ? true\n : matchPattern(pattern, value, selector),\n selections: selections,\n };\n },\n getSelectionKeys: () =>\n [key ?? symbols.anonymousSelectKey].concat(\n pattern === undefined ? [] : getSelectionKeys(pattern)\n ),\n };\n },\n });\n}\n\nfunction isUnknown(x: unknown): x is unknown {\n return true;\n}\n\nfunction isNumber(x: T | number): x is number {\n return typeof x === 'number';\n}\n\nfunction isString(x: T | string): x is string {\n return typeof x === 'string';\n}\n\nfunction isBoolean(x: T | boolean): x is boolean {\n return typeof x === 'boolean';\n}\n\nfunction isBigInt(x: T | bigint): x is bigint {\n return typeof x === 'bigint';\n}\n\nfunction isSymbol(x: T | symbol): x is symbol {\n return typeof x === 'symbol';\n}\n\nfunction isNullish(x: T | null | undefined): x is null | undefined {\n return x === null || x === undefined;\n}\n\nfunction isNonNullable(x: unknown): x is {} {\n return x !== null && x !== undefined;\n}\n\ntype AnyConstructor = abstract new (...args: any[]) => any;\n\nfunction isInstanceOf(classConstructor: T) {\n return (val: unknown): val is InstanceType =>\n val instanceof classConstructor;\n}\n\n/**\n * `P.any` is a wildcard pattern, matching **any value**.\n *\n * [Read the documentation for `P.any` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard)\n *\n * @example\n * match(value)\n * .with(P.any, () => 'will always match')\n */\nexport const any: AnyPattern = chainable(when(isUnknown));\n\n/**\n * `P._` is a wildcard pattern, matching **any value**.\n * It's an alias to `P.any`.\n *\n * [Read the documentation for `P._` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard)\n *\n * @example\n * match(value)\n * .with(P._, () => 'will always match')\n */\nexport const _ = any;\n\n/**\n * `P.string.startsWith(start)` is a pattern, matching **strings** starting with `start`.\n *\n * [Read the documentation for `P.string.startsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringstartsWith)\n *\n * @example\n * match(value)\n * .with(P.string.startsWith('A'), () => 'value starts with an A')\n */\n\nconst startsWith = (\n start: start\n): GuardP =>\n when((value) => isString(value) && value.startsWith(start));\n\n/**\n * `P.string.endsWith(end)` is a pattern, matching **strings** ending with `end`.\n *\n * [Read the documentation for `P.string.endsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringendsWith)\n *\n * @example\n * match(value)\n * .with(P.string.endsWith('!'), () => 'value ends with an !')\n */\nconst endsWith = (\n end: end\n): GuardP =>\n when((value) => isString(value) && value.endsWith(end));\n\n/**\n * `P.string.minLength(min)` is a pattern, matching **strings** with at least `min` characters.\n *\n * [Read the documentation for `P.string.minLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringminLength)\n *\n * @example\n * match(value)\n * .with(P.string.minLength(10), () => 'string with more length >= 10')\n */\nconst minLength = (min: min) =>\n when((value) => isString(value) && value.length >= min);\n\n/**\n * `P.string.length(len)` is a pattern, matching **strings** with exactly `len` characters.\n *\n * [Read the documentation for `P.string.length` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringlength)\n *\n * @example\n * match(value)\n * .with(P.string.length(10), () => 'strings with length === 10')\n */\nconst length = (len: len) =>\n when((value) => isString(value) && value.length === len);\n\n/**\n * `P.string.maxLength(max)` is a pattern, matching **strings** with at most `max` characters.\n *\n * [Read the documentation for `P.string.maxLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringmaxLength)\n *\n * @example\n * match(value)\n * .with(P.string.maxLength(10), () => 'string with more length <= 10')\n */\nconst maxLength = (max: max) =>\n when((value) => isString(value) && value.length <= max);\n\n/**\n * `P.string.includes(substr)` is a pattern, matching **strings** containing `substr`.\n *\n * [Read the documentation for `P.string.includes` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringincludes)\n *\n * @example\n * match(value)\n * .with(P.string.includes('http'), () => 'value contains http')\n */\nconst includes = (\n substr: substr\n): GuardExcludeP =>\n when((value) => isString(value) && value.includes(substr));\n\n/**\n * `P.string.regex(expr)` is a pattern, matching **strings** that `expr` regular expression.\n *\n * [Read the documentation for `P.string.regex` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringregex)\n *\n * @example\n * match(value)\n * .with(P.string.regex(/^https?:\\/\\//), () => 'url')\n */\nconst regex = (\n expr: expr\n): GuardExcludeP =>\n when((value) => isString(value) && Boolean(value.match(expr)));\n\nconst stringChainable = >(\n pattern: pattern\n): StringChainable =>\n Object.assign(chainable(pattern), {\n startsWith: (str: string) =>\n stringChainable(intersection(pattern, startsWith(str))),\n endsWith: (str: string) =>\n stringChainable(intersection(pattern, endsWith(str))),\n minLength: (min: number) =>\n stringChainable(intersection(pattern, minLength(min))),\n length: (len: number) =>\n stringChainable(intersection(pattern, length(len))),\n maxLength: (max: number) =>\n stringChainable(intersection(pattern, maxLength(max))),\n includes: (str: string) =>\n stringChainable(intersection(pattern, includes(str))),\n regex: (str: string) => stringChainable(intersection(pattern, regex(str))),\n }) as any;\n\n/**\n * `P.string` is a wildcard pattern, matching any **string**.\n *\n * [Read the documentation for `P.string` on GitHub](https://github.com/gvergnaud/ts-pattern#pstring-wildcard)\n *\n * @example\n * match(value)\n * .with(P.string, () => 'will match on strings')\n */\nexport const string: StringPattern = stringChainable(when(isString));\n\n/**\n * `P.number.between(min, max)` matches **numbers** between `min` and `max`,\n * equal to min or equal to max.\n *\n * [Read the documentation for `P.number.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween)\n *\n * @example\n * match(value)\n * .with(P.number.between(0, 10), () => '0 <= numbers <= 10')\n */\nconst between = (\n min: min,\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && min <= value && max >= value);\n\n/**\n * `P.number.lt(max)` matches **numbers** smaller than `max`.\n *\n * [Read the documentation for `P.number.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt)\n *\n * @example\n * match(value)\n * .with(P.number.lt(10), () => 'numbers < 10')\n */\nconst lt = (\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && value < max);\n\n/**\n * `P.number.gt(min)` matches **numbers** greater than `min`.\n *\n * [Read the documentation for `P.number.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt)\n *\n * @example\n * match(value)\n * .with(P.number.gt(10), () => 'numbers > 10')\n */\nconst gt = (\n min: min\n): GuardExcludeP =>\n when((value) => isNumber(value) && value > min);\n\n/**\n * `P.number.lte(max)` matches **numbers** smaller than or equal to `max`.\n *\n * [Read the documentation for `P.number.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte)\n *\n * @example\n * match(value)\n * .with(P.number.lte(10), () => 'numbers <= 10')\n */\nconst lte = (\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && value <= max);\n\n/**\n * `P.number.gte(min)` matches **numbers** greater than or equal to `min`.\n *\n * [Read the documentation for `P.number.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergte)\n *\n * @example\n * match(value)\n * .with(P.number.gte(10), () => 'numbers >= 10')\n */\nconst gte = (\n min: min\n): GuardExcludeP =>\n when((value) => isNumber(value) && value >= min);\n\n/**\n * `P.number.int()` matches **integer** numbers.\n *\n * [Read the documentation for `P.number.int()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberint)\n *\n * @example\n * match(value)\n * .with(P.number.int(), () => 'an integer')\n */\nconst int = (): GuardExcludeP =>\n when((value) => isNumber(value) && Number.isInteger(value));\n\n/**\n * `P.number.finite` matches **finite numbers**.\n *\n * [Read the documentation for `P.number.finite` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberfinite)\n *\n * @example\n * match(value)\n * .with(P.number.finite, () => 'not Infinity')\n */\nconst finite = (): GuardExcludeP =>\n when((value) => isNumber(value) && Number.isFinite(value));\n\n/**\n * `P.number.positive()` matches **positive** numbers.\n *\n * [Read the documentation for `P.number.positive()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberpositive)\n *\n * @example\n * match(value)\n * .with(P.number.positive(), () => 'number > 0')\n */\nconst positive = (): GuardExcludeP =>\n when((value) => isNumber(value) && value > 0);\n\n/**\n * `P.number.negative()` matches **negative** numbers.\n *\n * [Read the documentation for `P.number.negative()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbernegative)\n *\n * @example\n * match(value)\n * .with(P.number.negative(), () => 'number < 0')\n */\nconst negative = (): GuardExcludeP =>\n when((value) => isNumber(value) && value < 0);\n\nconst numberChainable = >(\n pattern: pattern\n): NumberChainable =>\n Object.assign(chainable(pattern), {\n between: (min: number, max: number) =>\n numberChainable(intersection(pattern, between(min, max))),\n lt: (max: number) => numberChainable(intersection(pattern, lt(max))),\n gt: (min: number) => numberChainable(intersection(pattern, gt(min))),\n lte: (max: number) => numberChainable(intersection(pattern, lte(max))),\n gte: (min: number) => numberChainable(intersection(pattern, gte(min))),\n int: () => numberChainable(intersection(pattern, int())),\n finite: () => numberChainable(intersection(pattern, finite())),\n positive: () => numberChainable(intersection(pattern, positive())),\n negative: () => numberChainable(intersection(pattern, negative())),\n }) as any;\n\n/**\n * `P.number` is a wildcard pattern, matching any **number**.\n *\n * [Read the documentation for `P.number` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumber-wildcard)\n *\n * @example\n * match(value)\n * .with(P.number, () => 'will match on numbers')\n */\nexport const number: NumberPattern = numberChainable(when(isNumber));\n\n/**\n * `P.bigint.between(min, max)` matches **bigint** between `min` and `max`,\n * equal to min or equal to max.\n *\n * [Read the documentation for `P.bigint.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween)\n *\n * @example\n * match(value)\n * .with(P.bigint.between(0, 10), () => '0 <= bigints <= 10')\n */\nconst betweenBigInt = <\n input,\n const min extends bigint,\n const max extends bigint\n>(\n min: min,\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && min <= value && max >= value);\n\n/**\n * `P.bigint.lt(max)` matches **bigint** smaller than `max`.\n *\n * [Read the documentation for `P.bigint.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt)\n *\n * @example\n * match(value)\n * .with(P.bigint.lt(10), () => 'bigints < 10')\n */\nconst ltBigInt = (\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value < max);\n\n/**\n * `P.bigint.gt(min)` matches **bigint** greater than `min`.\n *\n * [Read the documentation for `P.bigint.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt)\n *\n * @example\n * match(value)\n * .with(P.bigint.gt(10), () => 'bigints > 10')\n */\nconst gtBigInt = (\n min: min\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value > min);\n\n/**\n * `P.bigint.lte(max)` matches **bigint** smaller than or equal to `max`.\n *\n * [Read the documentation for `P.bigint.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte)\n *\n * @example\n * match(value)\n * .with(P.bigint.lte(10), () => 'bigints <= 10')\n */\nconst lteBigInt = (\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value <= max);\n\n/**\n * `P.bigint.gte(min)` matches **bigint** greater than or equal to `min`.\n *\n * [Read the documentation for `P.bigint.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintgte)\n *\n * @example\n * match(value)\n * .with(P.bigint.gte(10), () => 'bigints >= 10')\n */\nconst gteBigInt = (\n min: min\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value >= min);\n\n/**\n * `P.bigint.positive()` matches **positive** bigints.\n *\n * [Read the documentation for `P.bigint.positive()` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintpositive)\n *\n * @example\n * match(value)\n * .with(P.bigint.positive(), () => 'bigint > 0')\n */\nconst positiveBigInt = (): GuardExcludeP =>\n when((value) => isBigInt(value) && value > 0);\n\n/**\n * `P.bigint.negative()` matches **negative** bigints.\n *\n * [Read the documentation for `P.bigint.negative()` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintnegative)\n *\n * @example\n * match(value)\n * .with(P.bigint.negative(), () => 'bigint < 0')\n */\nconst negativeBigInt = (): GuardExcludeP =>\n when((value) => isBigInt(value) && value < 0);\n\nconst bigintChainable = >(\n pattern: pattern\n): BigIntChainable =>\n Object.assign(chainable(pattern), {\n between: (min: bigint, max: bigint) =>\n bigintChainable(intersection(pattern, betweenBigInt(min, max))),\n lt: (max: bigint) => bigintChainable(intersection(pattern, ltBigInt(max))),\n gt: (min: bigint) => bigintChainable(intersection(pattern, gtBigInt(min))),\n lte: (max: bigint) =>\n bigintChainable(intersection(pattern, lteBigInt(max))),\n gte: (min: bigint) =>\n bigintChainable(intersection(pattern, gteBigInt(min))),\n positive: () => bigintChainable(intersection(pattern, positiveBigInt())),\n negative: () => bigintChainable(intersection(pattern, negativeBigInt())),\n }) as any;\n\n/**\n * `P.bigint` is a wildcard pattern, matching any **bigint**.\n *\n * [Read the documentation for `P.bigint` on GitHub](https://github.com/gvergnaud/ts-pattern#number-wildcard)\n *\n * @example\n * .with(P.bigint, () => 'will match on bigints')\n */\nexport const bigint: BigIntPattern = bigintChainable(when(isBigInt));\n\n/**\n * `P.boolean` is a wildcard pattern, matching any **boolean**.\n *\n * [Read the documentation for `P.boolean` on GitHub](https://github.com/gvergnaud/ts-pattern#boolean-wildcard)\n *\n * @example\n * .with(P.boolean, () => 'will match on booleans')\n */\nexport const boolean: BooleanPattern = chainable(when(isBoolean));\n\n/**\n * `P.symbol` is a wildcard pattern, matching any **symbol**.\n *\n * [Read the documentation for `P.symbol` on GitHub](https://github.com/gvergnaud/ts-pattern#symbol-wildcard)\n *\n * @example\n * .with(P.symbol, () => 'will match on symbols')\n */\nexport const symbol: SymbolPattern = chainable(when(isSymbol));\n\n/**\n * `P.nullish` is a wildcard pattern, matching **null** or **undefined**.\n *\n * [Read the documentation for `P.nullish` on GitHub](https://github.com/gvergnaud/ts-pattern#nullish-wildcard)\n *\n * @example\n * .with(P.nullish, (x) => `${x} is null or undefined`)\n */\nexport const nullish: NullishPattern = chainable(when(isNullish));\n\n/**\n * `P.nonNullable` is a wildcard pattern, matching everything except **null** or **undefined**.\n *\n * [Read the documentation for `P.nonNullable` on GitHub](https://github.com/gvergnaud/ts-pattern#nonNullable-wildcard)\n *\n * @example\n * .with(P.nonNullable, (x) => `${x} isn't null nor undefined`)\n */\nexport const nonNullable: NonNullablePattern = chainable(when(isNonNullable));\n\n/**\n * `P.instanceOf(SomeClass)` is a pattern matching instances of a given class.\n *\n * [Read the documentation for `P.instanceOf` on GitHub](https://github.com/gvergnaud/ts-pattern#pinstanceof-patterns)\n *\n * @example\n * .with(P.instanceOf(SomeClass), () => 'will match on SomeClass instances')\n */\nexport function instanceOf(\n classConstructor: T\n): Chainable>> {\n return chainable(when(isInstanceOf(classConstructor)));\n}\n\n/**\n * `P.shape(somePattern)` lets you call methods like `.optional()`, `.and`, `.or` and `.select()`\n * On structural patterns, like objects and arrays.\n *\n * [Read the documentation for `P.shape` on GitHub](https://github.com/gvergnaud/ts-pattern#pshape-patterns)\n *\n * @example\n * .with(\n * {\n * state: P.shape({ status: \"success\" }).optional().select()\n * },\n * (state) => 'match the success state, or undefined.'\n * )\n */\nexport function shape>(\n pattern: pattern\n): Chainable>>;\nexport function shape(pattern: UnknownPattern) {\n return chainable(when(isMatching(pattern)));\n}\n","/**\n * Error when the given input value does not match any included pattern\n * and .exhaustive() was specified\n */\nexport class NonExhaustiveError extends Error {\n constructor(public input: unknown) {\n let displayedValue;\n try {\n displayedValue = JSON.stringify(input);\n } catch (e) {\n displayedValue = input;\n }\n super(`Pattern matching error: no pattern matches value ${displayedValue}`);\n }\n}\n","import { Pattern } from './types/Pattern';\nimport { Match } from './types/Match';\nimport * as symbols from './internals/symbols';\nimport { matchPattern } from './internals/helpers';\nimport { NonExhaustiveError } from './errors';\n\ntype MatchState =\n | { matched: true; value: output }\n | { matched: false; value: undefined };\n\nconst unmatched: MatchState = {\n matched: false,\n value: undefined,\n};\n\n/**\n * `match` creates a **pattern matching expression**.\n * * Use `.with(pattern, handler)` to pattern match on the input.\n * * Use `.exhaustive()` or `.otherwise(() => defaultValue)` to end the expression and get the result.\n *\n * [Read the documentation for `match` on GitHub](https://github.com/gvergnaud/ts-pattern#match)\n *\n * @example\n * declare let input: \"A\" | \"B\";\n *\n * return match(input)\n * .with(\"A\", () => \"It's an A!\")\n * .with(\"B\", () => \"It's a B!\")\n * .exhaustive();\n *\n */\nexport function match(\n value: input\n): Match {\n return new MatchExpression(value, unmatched) as any;\n}\n\n/**\n * This class represents a match expression. It follows the\n * builder pattern, we chain methods to add features to the expression\n * until we call `.exhaustive`, `.otherwise` or the unsafe `.run`\n * method to execute it.\n *\n * The types of this class aren't public, the public type definition\n * can be found in src/types/Match.ts.\n */\nclass MatchExpression {\n constructor(private input: input, private state: MatchState) {}\n\n with(...args: any[]): MatchExpression {\n if (this.state.matched) return this;\n\n const handler: (selection: unknown, value: input) => output =\n args[args.length - 1];\n\n const patterns: Pattern[] = [args[0]];\n let predicate: ((value: input) => unknown) | undefined = undefined;\n\n if (args.length === 3 && typeof args[1] === 'function') {\n // case with guard as second argument\n predicate = args[1];\n } else if (args.length > 2) {\n // case with several patterns\n patterns.push(...args.slice(1, args.length - 1));\n }\n\n let hasSelections = false;\n let selected: Record = {};\n const select = (key: string, value: unknown) => {\n hasSelections = true;\n selected[key] = value;\n };\n\n const matched =\n patterns.some((pattern) => matchPattern(pattern, this.input, select)) &&\n (predicate ? Boolean(predicate(this.input)) : true);\n\n const selections = hasSelections\n ? symbols.anonymousSelectKey in selected\n ? selected[symbols.anonymousSelectKey]\n : selected\n : this.input;\n\n const state = matched\n ? {\n matched: true as const,\n value: handler(selections, this.input),\n }\n : unmatched;\n\n return new MatchExpression(this.input, state);\n }\n\n when(\n predicate: (value: input) => unknown,\n handler: (selection: input, value: input) => output\n ): MatchExpression {\n if (this.state.matched) return this;\n\n const matched = Boolean(predicate(this.input));\n\n return new MatchExpression(\n this.input,\n matched\n ? { matched: true, value: handler(this.input, this.input) }\n : unmatched\n );\n }\n\n otherwise(handler: (value: input) => output): output {\n if (this.state.matched) return this.state.value;\n return handler(this.input);\n }\n\n exhaustive(): output {\n if (this.state.matched) return this.state.value;\n\n throw new NonExhaustiveError(this.input);\n }\n\n run(): output {\n return this.exhaustive();\n }\n\n returnType() {\n return this;\n }\n}\n"],"names":["matcher","Symbol","for","isVariadic","anonymousSelectKey","isObject","value","Boolean","isMatcher","x","symbols","matchPattern","pattern","select","matched","selections","match","Object","keys","forEach","key","Array","isArray","startPatterns","endPatterns","variadicPatterns","i","subpattern","push","length","Error","startValues","slice","endValues","middleValues","Infinity","every","subPattern","Reflect","ownKeys","k","matcherType","is","getSelectionKeys","_pattern$symbols$matc","_pattern$symbols$matc2","_pattern$symbols$matc3","call","flatMap","values","xs","f","reduce","acc","concat","isMatching","args","chainable","assign","optional","and","p2","intersection","or","union","undefined","arrayChainable","iterator","done","next","_values$i","at","variadic","selector","setEvery","set","predicate","mapEvery","map","entries","patterns","p","some","when","isNumber","isString","isBigInt","any","_","stringChainable","startsWith","str","start","endsWith","end","minLength","min","len","maxLength","max","includes","substr","regex","expr","string","numberChainable","between","lt","gt","lte","gte","int","Number","isInteger","finite","isFinite","positive","negative","number","bigintChainable","betweenBigInt","ltBigInt","gtBigInt","lteBigInt","gteBigInt","bigint","boolean","symbol","nullish","nonNullable","v","Set","size","Map","_args$","toString","patternKey","patternValue","keyMatch","valueMatch","classConstructor","val","isInstanceOf","NonExhaustiveError","constructor","input","displayedValue","JSON","stringify","e","super","this","unmatched","MatchExpression","state","with","handler","hasSelections","selected","otherwise","exhaustive","run","returnType"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.umd.js b/dist/index.umd.js new file mode 100644 index 00000000..9e78178d --- /dev/null +++ b/dist/index.umd.js @@ -0,0 +1,2 @@ +!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((n||self).tsPattern={})}(this,function(n){function t(n){return t=Object.setPrototypeOf?Object.getPrototypeOf:function(n){return n.__proto__||Object.getPrototypeOf(n)},t(n)}function e(n,t){return e=Object.setPrototypeOf||function(n,t){return n.__proto__=t,n},e(n,t)}function r(n,t,u){return r=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(n){return!1}}()?Reflect.construct:function(n,t,r){var u=[null];u.push.apply(u,t);var i=new(Function.bind.apply(n,u));return r&&e(i,r.prototype),i},r.apply(null,arguments)}function u(n){var i="function"==typeof Map?new Map:void 0;return u=function(n){if(null===n||-1===Function.toString.call(n).indexOf("[native code]"))return n;if("function"!=typeof n)throw new TypeError("Super expression must either be null or a function");if(void 0!==i){if(i.has(n))return i.get(n);i.set(n,u)}function u(){return r(n,arguments,t(this).constructor)}return u.prototype=Object.create(n.prototype,{constructor:{value:u,enumerable:!1,writable:!0,configurable:!0}}),e(u,n)},u(n)}function i(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e=n.length?{done:!0}:{done:!1,value:n[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var c=Symbol.for("@ts-pattern/matcher"),f=Symbol.for("@ts-pattern/isVariadic"),a="@ts-pattern/anonymous-select-key",l=function(n){return Boolean(n&&"object"==typeof n)},s=function(n){return n&&!!n[c]},h=function n(t,e,r){if(s(t)){var u=t[c]().match(e),i=u.matched,a=u.selections;return i&&a&&Object.keys(a).forEach(function(n){return r(n,a[n])}),i}if(l(t)){if(!l(e))return!1;if(Array.isArray(t)){if(!Array.isArray(e))return!1;for(var h,v=[],p=[],y=[],g=o(t.keys());!(h=g()).done;){var d=t[h.value];s(d)&&d[f]?y.push(d):y.length?p.push(d):v.push(d)}if(y.length){if(y.length>1)throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(e.length=n})}(e)))},length:function(e){return n(O(t,function(n){return j(function(t){return E(t)&&t.length===n})}(e)))},maxLength:function(e){return n(O(t,function(n){return j(function(t){return E(t)&&t.length<=n})}(e)))},includes:function(e){return n(O(t,(r=e,j(function(n){return E(n)&&n.includes(r)}))));var r},regex:function(e){return n(O(t,(r=e,j(function(n){return E(n)&&Boolean(n.match(r))}))));var r}})}(j(E)),B=function n(t){return Object.assign(g(t),{between:function(e,r){return n(O(t,function(n,t){return j(function(e){return A(e)&&n<=e&&t>=e})}(e,r)))},lt:function(e){return n(O(t,function(n){return j(function(t){return A(t)&&tn})}(e)))},lte:function(e){return n(O(t,function(n){return j(function(t){return A(t)&&t<=n})}(e)))},gte:function(e){return n(O(t,function(n){return j(function(t){return A(t)&&t>=n})}(e)))},int:function(){return n(O(t,j(function(n){return A(n)&&Number.isInteger(n)})))},finite:function(){return n(O(t,j(function(n){return A(n)&&Number.isFinite(n)})))},positive:function(){return n(O(t,j(function(n){return A(n)&&n>0})))},negative:function(){return n(O(t,j(function(n){return A(n)&&n<0})))}})}(j(A)),M=function n(t){return Object.assign(g(t),{between:function(e,r){return n(O(t,function(n,t){return j(function(e){return _(e)&&n<=e&&t>=e})}(e,r)))},lt:function(e){return n(O(t,function(n){return j(function(t){return _(t)&&tn})}(e)))},lte:function(e){return n(O(t,function(n){return j(function(t){return _(t)&&t<=n})}(e)))},gte:function(e){return n(O(t,function(n){return j(function(t){return _(t)&&t>=n})}(e)))},positive:function(){return n(O(t,j(function(n){return _(n)&&n>0})))},negative:function(){return n(O(t,j(function(n){return _(n)&&n<0})))}})}(j(_)),R=g(j(function(n){return"boolean"==typeof n})),I=g(j(function(n){return"symbol"==typeof n})),N=g(j(function(n){return null==n})),k=g(j(function(n){return null!=n})),W={__proto__:null,matcher:c,optional:m,array:function(){var n,t=[].slice.call(arguments);return d(((n={})[c]=function(){return{match:function(n){if(!Array.isArray(n))return{matched:!1};if(0===t.length)return{matched:!0};var e=t[0],r={};if(0===n.length)return v(e).forEach(function(n){r[n]=[]}),{matched:!0,selections:r};var u=function(n,t){r[n]=(r[n]||[]).concat([t])};return{matched:n.every(function(n){return h(e,n,u)}),selections:r}},getSelectionKeys:function(){return 0===t.length?[]:v(t[0])}}},n))},set:function(){var n,t=[].slice.call(arguments);return g(((n={})[c]=function(){return{match:function(n){if(!(n instanceof Set))return{matched:!1};var e={};if(0===n.size)return{matched:!0,selections:e};if(0===t.length)return{matched:!0};var r=function(n,t){e[n]=(e[n]||[]).concat([t])},u=t[0];return{matched:b(n,function(n){return h(u,n,r)}),selections:e}},getSelectionKeys:function(){return 0===t.length?[]:v(t[0])}}},n))},map:function(){var n,t=[].slice.call(arguments);return g(((n={})[c]=function(){return{match:function(n){if(!(n instanceof Map))return{matched:!1};var e={};if(0===n.size)return{matched:!0,selections:e};var r,u=function(n,t){e[n]=(e[n]||[]).concat([t])};if(0===t.length)return{matched:!0};if(1===t.length)throw new Error("`P.map` wasn't given enough arguments. Expected (key, value), received "+(null==(r=t[0])?void 0:r.toString()));var i=t[0],o=t[1];return{matched:w(n,function(n,t){var e=h(i,t,u),r=h(o,n,u);return e&&r}),selections:e}},getSelectionKeys:function(){return 0===t.length?[]:[].concat(v(t[0]),v(t[1]))}}},n))},intersection:O,union:S,not:function(n){var t;return g(((t={})[c]=function(){return{match:function(t){return{matched:!h(n,t,function(){})}},getSelectionKeys:function(){return[]},matcherType:"not"}},t))},when:j,select:x,any:P,_:K,string:T,number:B,bigint:M,boolean:R,symbol:I,nullish:N,nonNullable:k,instanceOf:function(n){return g(j(function(n){return function(t){return t instanceof n}}(n)))},shape:function(n){return g(j(y(n)))}},F=/*#__PURE__*/function(n){var t,r;function u(t){var e,r;try{r=JSON.stringify(t)}catch(n){r=t}return(e=n.call(this,"Pattern matching error: no pattern matches value "+r)||this).input=void 0,e.input=t,e}return r=n,(t=u).prototype=Object.create(r.prototype),t.prototype.constructor=t,e(t,r),u}(/*#__PURE__*/u(Error)),z={matched:!1,value:void 0},L=/*#__PURE__*/function(){function n(n,t){this.input=void 0,this.state=void 0,this.input=n,this.state=t}var t=n.prototype;return t.with=function(){var t=this,e=[].slice.call(arguments);if(this.state.matched)return this;var r=e[e.length-1],u=[e[0]],i=void 0;3===e.length&&"function"==typeof e[1]?i=e[1]:e.length>2&&u.push.apply(u,e.slice(1,e.length-1));var o=!1,c={},f=function(n,t){o=!0,c[n]=t},l=!u.some(function(n){return h(n,t.input,f)})||i&&!Boolean(i(this.input))?z:{matched:!0,value:r(o?a in c?c[a]:c:this.input,this.input)};return new n(this.input,l)},t.when=function(t,e){if(this.state.matched)return this;var r=Boolean(t(this.input));return new n(this.input,r?{matched:!0,value:e(this.input,this.input)}:z)},t.otherwise=function(n){return this.state.matched?this.state.value:n(this.input)},t.exhaustive=function(){if(this.state.matched)return this.state.value;throw new F(this.input)},t.run=function(){return this.exhaustive()},t.returnType=function(){return this},n}();n.NonExhaustiveError=F,n.P=W,n.Pattern=W,n.isMatching=y,n.match=function(n){return new L(n,z)}}); +//# sourceMappingURL=index.umd.js.map diff --git a/dist/index.umd.js.map b/dist/index.umd.js.map new file mode 100644 index 00000000..81a39148 --- /dev/null +++ b/dist/index.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.umd.js","sources":["../src/internals/symbols.ts","../src/internals/helpers.ts","../src/is-matching.ts","../src/patterns.ts","../src/errors.ts","../src/match.ts"],"sourcesContent":["/**\n * Symbols used internally within ts-pattern to construct and discriminate\n * Guard, Not, and Select, and AnonymousSelect patterns\n *\n * Symbols have the advantage of not appearing in auto-complete suggestions in\n * user defined patterns, and eliminate the risk of property\n * overlap between ts-pattern internals and user defined patterns.\n *\n * These symbols have to be visible to tsc for type inference to work, but\n * users should not import them\n * @module\n * @private\n * @internal\n */\n\nexport const matcher = Symbol.for('@ts-pattern/matcher');\nexport type matcher = typeof matcher;\n\nexport const unset = Symbol.for('@ts-pattern/unset');\nexport type unset = typeof unset;\n\nexport const isVariadic = Symbol.for('@ts-pattern/isVariadic');\nexport type isVariadic = typeof isVariadic;\n\n// can't be a symbol because this key has to be enumerable.\nexport const anonymousSelectKey = '@ts-pattern/anonymous-select-key';\nexport type anonymousSelectKey = typeof anonymousSelectKey;\n\nexport const override = Symbol.for('@ts-pattern/override');\nexport type override = typeof override;\n","/**\n * @module\n * @private\n * @internal\n */\n\nimport * as symbols from './symbols';\nimport { SelectionType } from '../types/FindSelected';\nimport { Pattern, Matcher, MatcherType, AnyMatcher } from '../types/Pattern';\n\n// @internal\nexport const isObject = (value: unknown): value is Object =>\n Boolean(value && typeof value === 'object');\n\n// @internal\nexport const isMatcher = (\n x: unknown\n): x is Matcher => {\n const pattern = x as Matcher;\n return pattern && !!pattern[symbols.matcher];\n};\n\n// @internal\nconst isOptionalPattern = (\n x: unknown\n): x is Matcher => {\n return isMatcher(x) && x[symbols.matcher]().matcherType === 'optional';\n};\n\n// tells us if the value matches a given pattern.\n// @internal\nexport const matchPattern = (\n pattern: any,\n value: any,\n select: (key: string, value: unknown) => void\n): boolean => {\n if (isMatcher(pattern)) {\n const matcher = pattern[symbols.matcher]();\n const { matched, selections } = matcher.match(value);\n if (matched && selections) {\n Object.keys(selections).forEach((key) => select(key, selections[key]));\n }\n return matched;\n }\n\n if (isObject(pattern)) {\n if (!isObject(value)) return false;\n\n // Tuple pattern\n if (Array.isArray(pattern)) {\n if (!Array.isArray(value)) return false;\n let startPatterns = [];\n let endPatterns = [];\n let variadicPatterns: AnyMatcher[] = [];\n\n for (const i of pattern.keys()) {\n const subpattern = pattern[i];\n if (isMatcher(subpattern) && subpattern[symbols.isVariadic]) {\n variadicPatterns.push(subpattern);\n } else if (variadicPatterns.length) {\n endPatterns.push(subpattern);\n } else {\n startPatterns.push(subpattern);\n }\n }\n\n if (variadicPatterns.length) {\n if (variadicPatterns.length > 1) {\n throw new Error(\n `Pattern error: Using \\`...P.array(...)\\` several times in a single pattern is not allowed.`\n );\n }\n\n if (value.length < startPatterns.length + endPatterns.length) {\n return false;\n }\n\n const startValues = value.slice(0, startPatterns.length);\n const endValues =\n endPatterns.length === 0 ? [] : value.slice(-endPatterns.length);\n const middleValues = value.slice(\n startPatterns.length,\n endPatterns.length === 0 ? Infinity : -endPatterns.length\n );\n\n return (\n startPatterns.every((subPattern, i) =>\n matchPattern(subPattern, startValues[i], select)\n ) &&\n endPatterns.every((subPattern, i) =>\n matchPattern(subPattern, endValues[i], select)\n ) &&\n (variadicPatterns.length === 0\n ? true\n : matchPattern(variadicPatterns[0], middleValues, select))\n );\n }\n\n return pattern.length === value.length\n ? pattern.every((subPattern, i) =>\n matchPattern(subPattern, value[i], select)\n )\n : false;\n }\n\n return Reflect.ownKeys(pattern).every((k): boolean => {\n const subPattern = pattern[k];\n\n return (\n (k in value || isOptionalPattern(subPattern)) &&\n matchPattern(subPattern, value[k], select)\n );\n });\n }\n\n return Object.is(value, pattern);\n};\n\n// @internal\nexport const getSelectionKeys = (pattern: any): string[] => {\n if (isObject(pattern)) {\n if (isMatcher(pattern)) {\n return pattern[symbols.matcher]().getSelectionKeys?.() ?? [];\n }\n if (Array.isArray(pattern)) return flatMap(pattern, getSelectionKeys);\n return flatMap(Object.values(pattern), getSelectionKeys);\n }\n return [];\n};\n\n// @internal\nexport const flatMap = (\n xs: readonly a[],\n f: (v: a) => readonly b[]\n): b[] => xs.reduce((acc, x) => acc.concat(f(x)), []);\n","import { MatchedValue, Pattern } from './types/Pattern';\nimport * as P from './patterns';\nimport { matchPattern } from './internals/helpers';\n\n/**\n * `isMatching` takes pattern and returns a **type guard** function, cheching if a value matches this pattern.\n *\n * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching)\n *\n * @example\n * const hasName = isMatching({ name: P.string })\n *\n * declare let input: unknown\n *\n * if (hasName(input)) {\n * // `input` inferred as { name: string }\n * return input.name\n * }\n */\nexport function isMatching>(\n pattern: p\n): (value: unknown) => value is P.infer

;\n/**\n * `isMatching` takes pattern and a value and checks if the value matches this pattern.\n *\n * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching)\n *\n * @example\n * declare let input: unknown\n *\n * if (isMatching({ name: P.string }, input)) {\n * // `input` inferred as { name: string }\n * return input.name\n * }\n */\nexport function isMatching>(\n pattern: p,\n value: unknown\n): value is P.infer

;\n\nexport function isMatching>(\n ...args: [pattern: p, value?: any]\n): boolean | ((vale: any) => boolean) {\n if (args.length === 1) {\n const [pattern] = args;\n return (value: any): value is MatchedValue> =>\n matchPattern(pattern, value, () => {});\n }\n if (args.length === 2) {\n const [pattern, value] = args;\n return matchPattern(pattern, value, () => {});\n }\n\n throw new Error(\n `isMatching wasn't given the right number of arguments: expected 1 or 2, received ${args.length}.`\n );\n}\n","import { matchPattern, getSelectionKeys, flatMap } from './internals/helpers';\nimport * as symbols from './internals/symbols';\nimport { matcher } from './internals/symbols';\nimport { isMatching } from './is-matching';\nimport { ExtractPreciseValue } from './types/ExtractPreciseValue';\nimport { Fn } from './types/helpers';\nimport { InvertPattern } from './types/InvertPattern';\nimport {\n Pattern,\n UnknownPattern,\n OptionalP,\n ArrayP,\n MapP,\n SetP,\n AndP,\n OrP,\n NotP,\n GuardP,\n SelectP,\n AnonymousSelectP,\n GuardExcludeP,\n CustomP,\n Matcher,\n StringPattern,\n AnyPattern,\n NumberPattern,\n BooleanPattern,\n BigIntPattern,\n NullishPattern,\n SymbolPattern,\n Chainable,\n BigIntChainable,\n NumberChainable,\n StringChainable,\n ArrayChainable,\n Variadic,\n NonNullablePattern,\n} from './types/Pattern';\n\nexport type { Pattern, Fn as unstable_Fn };\n\nexport { matcher };\n\n/**\n * @experimental\n * A `Matchable` is an object implementing\n * the Matcher Protocol. It must have a `[P.matcher]: P.Matcher`\n * key, which defines how this object should be matched by TS-Pattern.\n *\n * Note that this api is unstable.\n *\n * @example\n * ```ts\n * class Some implements P.unstable_Matchable {\n * [P.matcher](): P.unstable_Matcher>\n * }\n * ```\n */\nexport type unstable_Matchable<\n narrowedOrFn,\n input = unknown,\n pattern = never\n> = CustomP;\n\n/**\n * @experimental\n * A `Matcher` is an object with `match` function, which\n * defines how this object should be matched by TS-Pattern.\n *\n * Note that this api is unstable.\n *\n * @example\n * ```ts\n * class Some implements P.unstable_Matchable {\n * [P.matcher](): P.unstable_Matcher>\n * }\n * ```\n */\nexport type unstable_Matcher<\n narrowedOrFn,\n input = unknown,\n pattern = never\n> = ReturnType[matcher]>;\n\n/**\n * `P.infer` will return the type of the value\n * matched by this pattern.\n *\n * [Read the documentation for `P.infer` on GitHub](https://github.com/gvergnaud/ts-pattern#pinfer)\n *\n * @example\n * const userPattern = { name: P.string }\n * type User = P.infer\n */\nexport type infer> = InvertPattern<\n pattern,\n unknown\n>;\n\n/**\n * `P.narrow` will narrow the input type to only keep\n * the set of values that are compatible with the provided pattern type.\n *\n * [Read the documentation for `P.narrow` on GitHub](https://github.com/gvergnaud/ts-pattern#pnarrow)\n *\n * @example\n * type Input = ['a' | 'b' | 'c', 'a' | 'b' | 'c']\n * const Pattern = ['a', P.union('a', 'b')] as const\n *\n * type Narrowed = P.narrow\n * // ^? ['a', 'a' | 'b']\n */\nexport type narrow> = ExtractPreciseValue<\n input,\n InvertPattern\n>;\n\nfunction chainable>(\n pattern: pattern\n): Chainable {\n return Object.assign(pattern, {\n optional: () => optional(pattern),\n and: (p2: any) => intersection(pattern, p2),\n or: (p2: any) => union(pattern, p2),\n select: (key: any) =>\n key === undefined ? select(pattern) : select(key, pattern),\n }) as Chainable;\n}\n\nconst variadic = (pattern: pattern): Variadic =>\n Object.assign(pattern, {\n [Symbol.iterator](): Iterator {\n let i = 0;\n const variadicPattern = Object.assign(pattern, {\n [symbols.isVariadic]: true,\n });\n const values: IteratorResult[] = [\n { value: variadicPattern, done: false },\n { done: true, value: undefined },\n ];\n return {\n next: () => values[i++] ?? values.at(-1)!,\n };\n },\n });\n\nfunction arrayChainable>(\n pattern: pattern\n): ArrayChainable {\n return Object.assign(variadic(pattern), {\n optional: () => arrayChainable(optional(pattern)),\n select: (key: any) =>\n arrayChainable(\n key === undefined ? select(pattern) : select(key, pattern)\n ),\n }) as any;\n}\n\n/**\n * `P.optional(subpattern)` takes a sub pattern and returns a pattern which matches if the\n * key is undefined or if it is defined and the sub pattern matches its value.\n *\n * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns)\n *\n * @example\n * match(value)\n * .with({ greeting: P.optional('Hello') }, () => 'will match { greeting?: \"Hello\" }')\n */\nexport function optional<\n input,\n const pattern extends unknown extends input ? UnknownPattern : Pattern\n>(pattern: pattern): Chainable, 'optional'> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n if (value === undefined) {\n getSelectionKeys(pattern).forEach((key) =>\n selector(key, undefined)\n );\n return { matched: true, selections };\n }\n const matched = matchPattern(pattern, value, selector);\n return { matched, selections };\n },\n getSelectionKeys: () => getSelectionKeys(pattern),\n matcherType: 'optional',\n };\n },\n });\n}\n\ntype UnwrapArray = xs extends readonly (infer x)[] ? x : never;\n\ntype UnwrapSet = xs extends Set ? x : never;\n\ntype UnwrapMapKey = xs extends Map ? k : never;\n\ntype UnwrapMapValue = xs extends Map ? v : never;\n\ntype WithDefault = [a] extends [never] ? b : a;\n\n/**\n * `P.array(subpattern)` takes a sub pattern and returns a pattern, which matches\n * arrays if all their elements match the sub pattern.\n *\n * [Read the documentation for `P.array` on GitHub](https://github.com/gvergnaud/ts-pattern#parray-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.array({ name: P.string }) }, () => 'will match { name: string }[]')\n */\nexport function array(): ArrayChainable>;\nexport function array<\n input,\n const pattern extends Pattern, unknown>>\n>(pattern: pattern): ArrayChainable>;\nexport function array(\n ...args: [pattern?: any]\n): ArrayChainable> {\n return arrayChainable({\n [matcher]() {\n return {\n match: (value: any) => {\n if (!Array.isArray(value)) return { matched: false };\n\n if (args.length === 0) return { matched: true };\n\n const pattern = args[0];\n let selections: Record = {};\n\n if (value.length === 0) {\n getSelectionKeys(pattern).forEach((key) => {\n selections[key] = [];\n });\n return { matched: true, selections };\n }\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n const matched = value.every((v) =>\n matchPattern(pattern, v, selector)\n );\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0 ? [] : getSelectionKeys(args[0]),\n };\n },\n });\n}\n\n/**\n * `P.set(subpattern)` takes a sub pattern and returns a pattern that matches\n * sets if all their elements match the sub pattern.\n *\n * [Read `P.set` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pset-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.set(P.string) }, () => 'will match Set')\n */\nexport function set(): Chainable>;\nexport function set<\n input,\n const pattern extends Pattern, unknown>>\n>(pattern: pattern): Chainable>;\nexport function set<\n input,\n const pattern extends Pattern, unknown>>\n>(...args: [pattern?: pattern]): Chainable> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n if (!(value instanceof Set)) return { matched: false };\n\n let selections: Record = {};\n\n if (value.size === 0) {\n return { matched: true, selections };\n }\n\n if (args.length === 0) return { matched: true };\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n const pattern = args[0];\n\n const matched = setEvery(value, (v) =>\n matchPattern(pattern, v, selector)\n );\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0 ? [] : getSelectionKeys(args[0]),\n };\n },\n });\n}\n\nconst setEvery = (set: Set, predicate: (value: T) => boolean) => {\n for (const value of set) {\n if (predicate(value)) continue;\n return false;\n }\n return true;\n};\n\n/**\n * `P.map(keyPattern, valuePattern)` takes a subpattern to match against the\n * key, a subpattern to match against the value and returns a pattern that\n * matches on maps where all elements inside the map match those two\n * subpatterns.\n *\n * [Read `P.map` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pmap-patterns)\n *\n * @example\n * match(value)\n * .with({ users: P.map(P.map(P.string, P.number)) }, (map) => `map's type is Map`)\n */\nexport function map(): Chainable>;\nexport function map<\n input,\n const pkey extends Pattern, unknown>>,\n const pvalue extends Pattern, unknown>>\n>(patternKey: pkey, patternValue: pvalue): Chainable>;\nexport function map<\n input,\n const pkey extends Pattern, unknown>>,\n const pvalue extends Pattern, unknown>>\n>(\n ...args: [patternKey?: pkey, patternValue?: pvalue]\n): Chainable> {\n return chainable({\n [matcher]() {\n return {\n match: (value: UnknownInput | input) => {\n if (!(value instanceof Map)) return { matched: false };\n\n let selections: Record = {};\n\n if (value.size === 0) {\n return { matched: true, selections };\n }\n\n const selector = (key: string, value: unknown) => {\n selections[key] = (selections[key] || []).concat([value]);\n };\n\n if (args.length === 0) return { matched: true };\n if (args.length === 1) {\n throw new Error(\n `\\`P.map\\` wasn\\'t given enough arguments. Expected (key, value), received ${args[0]?.toString()}`\n );\n }\n const [patternKey, patternValue] = args;\n\n const matched = mapEvery(value, (v, k) => {\n const keyMatch = matchPattern(patternKey, k, selector);\n const valueMatch = matchPattern(patternValue, v, selector);\n return keyMatch && valueMatch;\n });\n\n return { matched, selections };\n },\n getSelectionKeys: () =>\n args.length === 0\n ? []\n : [...getSelectionKeys(args[0]), ...getSelectionKeys(args[1])],\n };\n },\n });\n}\n\nconst mapEvery = (\n map: Map,\n predicate: (value: T, key: K) => boolean\n) => {\n for (const [key, value] of map.entries()) {\n if (predicate(value, key)) continue;\n return false;\n }\n return true;\n};\n\n/**\n * `P.intersection(...patterns)` returns a pattern which matches\n * only if **every** patterns provided in parameter match the input.\n *\n * [Read the documentation for `P.intersection` on GitHub](https://github.com/gvergnaud/ts-pattern#pintersection-patterns)\n *\n * @example\n * match(value)\n * .with(\n * {\n * user: P.intersection(\n * { firstname: P.string },\n * { lastname: P.string },\n * { age: P.when(age => age > 21) }\n * )\n * },\n * ({ user }) => 'will match { firstname: string, lastname: string, age: number } if age > 21'\n * )\n */\nexport function intersection<\n input,\n const patterns extends readonly [Pattern, ...Pattern[]]\n>(...patterns: patterns): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n const matched = (patterns as readonly UnknownPattern[]).every((p) =>\n matchPattern(p, value, selector)\n );\n return { matched, selections };\n },\n getSelectionKeys: () =>\n flatMap(patterns as readonly UnknownPattern[], getSelectionKeys),\n matcherType: 'and',\n }),\n });\n}\n\n/**\n * `P.union(...patterns)` returns a pattern which matches\n * if **at least one** of the patterns provided in parameter match the input.\n *\n * [Read the documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#punion-patterns)\n *\n * @example\n * match(value)\n * .with(\n * { type: P.union('a', 'b', 'c') },\n * ({ type }) => 'will match { type: \"a\" | \"b\" | \"c\" }'\n * )\n */\nexport function union<\n input,\n const patterns extends readonly [Pattern, ...Pattern[]]\n>(...patterns: patterns): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value: UnknownInput | input) => {\n let selections: Record = {};\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n flatMap(\n patterns as readonly UnknownPattern[],\n getSelectionKeys\n ).forEach((key) => selector(key, undefined));\n const matched = (patterns as readonly UnknownPattern[]).some((p) =>\n matchPattern(p, value, selector)\n );\n return { matched, selections };\n },\n getSelectionKeys: () =>\n flatMap(patterns as readonly UnknownPattern[], getSelectionKeys),\n matcherType: 'or',\n }),\n });\n}\n\n/**\n * `P.not(pattern)` returns a pattern which matches if the sub pattern\n * doesn't match.\n *\n * [Read the documentation for `P.not` on GitHub](https://github.com/gvergnaud/ts-pattern#pnot-patterns)\n *\n * @example\n * match<{ a: string | number }>(value)\n * .with({ a: P.not(P.string) }, (x) => 'will match { a: number }'\n * )\n */\n\nexport function not<\n input,\n const pattern extends Pattern | UnknownPattern\n>(pattern: pattern): Chainable> {\n return chainable({\n [matcher]: () => ({\n match: (value: UnknownInput | input) => ({\n matched: !matchPattern(pattern, value, () => {}),\n }),\n getSelectionKeys: () => [],\n matcherType: 'not',\n }),\n });\n}\n\n/**\n * `P.when((value) => boolean)` returns a pattern which matches\n * if the predicate returns true for the current input.\n *\n * [Read the documentation for `P.when` on GitHub](https://github.com/gvergnaud/ts-pattern#pwhen-patterns)\n *\n * @example\n * match<{ age: number }>(value)\n * .with({ age: P.when(age => age > 21) }, (x) => 'will match if value.age > 21'\n * )\n */\nexport function when unknown>(\n predicate: predicate\n): GuardP<\n input,\n predicate extends (value: any) => value is infer narrowed ? narrowed : never\n>;\nexport function when(\n predicate: (input: input) => input is narrowed\n): GuardExcludeP;\nexport function when unknown>(\n predicate: predicate\n): GuardP<\n input,\n predicate extends (value: any) => value is infer narrowed ? narrowed : never\n> {\n return {\n [matcher]: () => ({\n match: (value: UnknownInput | input) => ({\n matched: Boolean(predicate(value as input)),\n }),\n }),\n };\n}\n\n/**\n * `P.select()` is a pattern which will always match,\n * and will inject the selected piece of input in the handler function.\n *\n * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns)\n *\n * @example\n * match<{ age: number }>(value)\n * .with({ age: P.select() }, (age) => 'age: number'\n * )\n */\nexport function select(): Chainable;\nexport function select<\n input,\n const patternOrKey extends\n | string\n | (unknown extends input ? UnknownPattern : Pattern)\n>(\n patternOrKey: patternOrKey\n): patternOrKey extends string\n ? Chainable>\n : Chainable<\n SelectP,\n 'select' | 'or' | 'and'\n >;\nexport function select<\n input,\n const pattern extends unknown extends input ? UnknownPattern : Pattern,\n const k extends string\n>(\n key: k,\n pattern: pattern\n): Chainable, 'select' | 'or' | 'and'>;\nexport function select(\n ...args: [keyOrPattern?: unknown | string, pattern?: unknown]\n): Chainable, 'select' | 'or' | 'and'> {\n const key: string | undefined =\n typeof args[0] === 'string' ? args[0] : undefined;\n const pattern: unknown =\n args.length === 2\n ? args[1]\n : typeof args[0] === 'string'\n ? undefined\n : args[0];\n return chainable({\n [matcher]() {\n return {\n match: (value) => {\n let selections: Record = {\n [key ?? symbols.anonymousSelectKey]: value,\n };\n const selector = (key: string, value: any) => {\n selections[key] = value;\n };\n return {\n matched:\n pattern === undefined\n ? true\n : matchPattern(pattern, value, selector),\n selections: selections,\n };\n },\n getSelectionKeys: () =>\n [key ?? symbols.anonymousSelectKey].concat(\n pattern === undefined ? [] : getSelectionKeys(pattern)\n ),\n };\n },\n });\n}\n\nfunction isUnknown(x: unknown): x is unknown {\n return true;\n}\n\nfunction isNumber(x: T | number): x is number {\n return typeof x === 'number';\n}\n\nfunction isString(x: T | string): x is string {\n return typeof x === 'string';\n}\n\nfunction isBoolean(x: T | boolean): x is boolean {\n return typeof x === 'boolean';\n}\n\nfunction isBigInt(x: T | bigint): x is bigint {\n return typeof x === 'bigint';\n}\n\nfunction isSymbol(x: T | symbol): x is symbol {\n return typeof x === 'symbol';\n}\n\nfunction isNullish(x: T | null | undefined): x is null | undefined {\n return x === null || x === undefined;\n}\n\nfunction isNonNullable(x: unknown): x is {} {\n return x !== null && x !== undefined;\n}\n\ntype AnyConstructor = abstract new (...args: any[]) => any;\n\nfunction isInstanceOf(classConstructor: T) {\n return (val: unknown): val is InstanceType =>\n val instanceof classConstructor;\n}\n\n/**\n * `P.any` is a wildcard pattern, matching **any value**.\n *\n * [Read the documentation for `P.any` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard)\n *\n * @example\n * match(value)\n * .with(P.any, () => 'will always match')\n */\nexport const any: AnyPattern = chainable(when(isUnknown));\n\n/**\n * `P._` is a wildcard pattern, matching **any value**.\n * It's an alias to `P.any`.\n *\n * [Read the documentation for `P._` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard)\n *\n * @example\n * match(value)\n * .with(P._, () => 'will always match')\n */\nexport const _ = any;\n\n/**\n * `P.string.startsWith(start)` is a pattern, matching **strings** starting with `start`.\n *\n * [Read the documentation for `P.string.startsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringstartsWith)\n *\n * @example\n * match(value)\n * .with(P.string.startsWith('A'), () => 'value starts with an A')\n */\n\nconst startsWith = (\n start: start\n): GuardP =>\n when((value) => isString(value) && value.startsWith(start));\n\n/**\n * `P.string.endsWith(end)` is a pattern, matching **strings** ending with `end`.\n *\n * [Read the documentation for `P.string.endsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringendsWith)\n *\n * @example\n * match(value)\n * .with(P.string.endsWith('!'), () => 'value ends with an !')\n */\nconst endsWith = (\n end: end\n): GuardP =>\n when((value) => isString(value) && value.endsWith(end));\n\n/**\n * `P.string.minLength(min)` is a pattern, matching **strings** with at least `min` characters.\n *\n * [Read the documentation for `P.string.minLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringminLength)\n *\n * @example\n * match(value)\n * .with(P.string.minLength(10), () => 'string with more length >= 10')\n */\nconst minLength = (min: min) =>\n when((value) => isString(value) && value.length >= min);\n\n/**\n * `P.string.length(len)` is a pattern, matching **strings** with exactly `len` characters.\n *\n * [Read the documentation for `P.string.length` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringlength)\n *\n * @example\n * match(value)\n * .with(P.string.length(10), () => 'strings with length === 10')\n */\nconst length = (len: len) =>\n when((value) => isString(value) && value.length === len);\n\n/**\n * `P.string.maxLength(max)` is a pattern, matching **strings** with at most `max` characters.\n *\n * [Read the documentation for `P.string.maxLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringmaxLength)\n *\n * @example\n * match(value)\n * .with(P.string.maxLength(10), () => 'string with more length <= 10')\n */\nconst maxLength = (max: max) =>\n when((value) => isString(value) && value.length <= max);\n\n/**\n * `P.string.includes(substr)` is a pattern, matching **strings** containing `substr`.\n *\n * [Read the documentation for `P.string.includes` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringincludes)\n *\n * @example\n * match(value)\n * .with(P.string.includes('http'), () => 'value contains http')\n */\nconst includes = (\n substr: substr\n): GuardExcludeP =>\n when((value) => isString(value) && value.includes(substr));\n\n/**\n * `P.string.regex(expr)` is a pattern, matching **strings** that `expr` regular expression.\n *\n * [Read the documentation for `P.string.regex` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringregex)\n *\n * @example\n * match(value)\n * .with(P.string.regex(/^https?:\\/\\//), () => 'url')\n */\nconst regex = (\n expr: expr\n): GuardExcludeP =>\n when((value) => isString(value) && Boolean(value.match(expr)));\n\nconst stringChainable = >(\n pattern: pattern\n): StringChainable =>\n Object.assign(chainable(pattern), {\n startsWith: (str: string) =>\n stringChainable(intersection(pattern, startsWith(str))),\n endsWith: (str: string) =>\n stringChainable(intersection(pattern, endsWith(str))),\n minLength: (min: number) =>\n stringChainable(intersection(pattern, minLength(min))),\n length: (len: number) =>\n stringChainable(intersection(pattern, length(len))),\n maxLength: (max: number) =>\n stringChainable(intersection(pattern, maxLength(max))),\n includes: (str: string) =>\n stringChainable(intersection(pattern, includes(str))),\n regex: (str: string) => stringChainable(intersection(pattern, regex(str))),\n }) as any;\n\n/**\n * `P.string` is a wildcard pattern, matching any **string**.\n *\n * [Read the documentation for `P.string` on GitHub](https://github.com/gvergnaud/ts-pattern#pstring-wildcard)\n *\n * @example\n * match(value)\n * .with(P.string, () => 'will match on strings')\n */\nexport const string: StringPattern = stringChainable(when(isString));\n\n/**\n * `P.number.between(min, max)` matches **numbers** between `min` and `max`,\n * equal to min or equal to max.\n *\n * [Read the documentation for `P.number.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween)\n *\n * @example\n * match(value)\n * .with(P.number.between(0, 10), () => '0 <= numbers <= 10')\n */\nconst between = (\n min: min,\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && min <= value && max >= value);\n\n/**\n * `P.number.lt(max)` matches **numbers** smaller than `max`.\n *\n * [Read the documentation for `P.number.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt)\n *\n * @example\n * match(value)\n * .with(P.number.lt(10), () => 'numbers < 10')\n */\nconst lt = (\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && value < max);\n\n/**\n * `P.number.gt(min)` matches **numbers** greater than `min`.\n *\n * [Read the documentation for `P.number.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt)\n *\n * @example\n * match(value)\n * .with(P.number.gt(10), () => 'numbers > 10')\n */\nconst gt = (\n min: min\n): GuardExcludeP =>\n when((value) => isNumber(value) && value > min);\n\n/**\n * `P.number.lte(max)` matches **numbers** smaller than or equal to `max`.\n *\n * [Read the documentation for `P.number.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte)\n *\n * @example\n * match(value)\n * .with(P.number.lte(10), () => 'numbers <= 10')\n */\nconst lte = (\n max: max\n): GuardExcludeP =>\n when((value) => isNumber(value) && value <= max);\n\n/**\n * `P.number.gte(min)` matches **numbers** greater than or equal to `min`.\n *\n * [Read the documentation for `P.number.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergte)\n *\n * @example\n * match(value)\n * .with(P.number.gte(10), () => 'numbers >= 10')\n */\nconst gte = (\n min: min\n): GuardExcludeP =>\n when((value) => isNumber(value) && value >= min);\n\n/**\n * `P.number.int()` matches **integer** numbers.\n *\n * [Read the documentation for `P.number.int()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberint)\n *\n * @example\n * match(value)\n * .with(P.number.int(), () => 'an integer')\n */\nconst int = (): GuardExcludeP =>\n when((value) => isNumber(value) && Number.isInteger(value));\n\n/**\n * `P.number.finite` matches **finite numbers**.\n *\n * [Read the documentation for `P.number.finite` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberfinite)\n *\n * @example\n * match(value)\n * .with(P.number.finite, () => 'not Infinity')\n */\nconst finite = (): GuardExcludeP =>\n when((value) => isNumber(value) && Number.isFinite(value));\n\n/**\n * `P.number.positive()` matches **positive** numbers.\n *\n * [Read the documentation for `P.number.positive()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberpositive)\n *\n * @example\n * match(value)\n * .with(P.number.positive(), () => 'number > 0')\n */\nconst positive = (): GuardExcludeP =>\n when((value) => isNumber(value) && value > 0);\n\n/**\n * `P.number.negative()` matches **negative** numbers.\n *\n * [Read the documentation for `P.number.negative()` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbernegative)\n *\n * @example\n * match(value)\n * .with(P.number.negative(), () => 'number < 0')\n */\nconst negative = (): GuardExcludeP =>\n when((value) => isNumber(value) && value < 0);\n\nconst numberChainable = >(\n pattern: pattern\n): NumberChainable =>\n Object.assign(chainable(pattern), {\n between: (min: number, max: number) =>\n numberChainable(intersection(pattern, between(min, max))),\n lt: (max: number) => numberChainable(intersection(pattern, lt(max))),\n gt: (min: number) => numberChainable(intersection(pattern, gt(min))),\n lte: (max: number) => numberChainable(intersection(pattern, lte(max))),\n gte: (min: number) => numberChainable(intersection(pattern, gte(min))),\n int: () => numberChainable(intersection(pattern, int())),\n finite: () => numberChainable(intersection(pattern, finite())),\n positive: () => numberChainable(intersection(pattern, positive())),\n negative: () => numberChainable(intersection(pattern, negative())),\n }) as any;\n\n/**\n * `P.number` is a wildcard pattern, matching any **number**.\n *\n * [Read the documentation for `P.number` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumber-wildcard)\n *\n * @example\n * match(value)\n * .with(P.number, () => 'will match on numbers')\n */\nexport const number: NumberPattern = numberChainable(when(isNumber));\n\n/**\n * `P.bigint.between(min, max)` matches **bigint** between `min` and `max`,\n * equal to min or equal to max.\n *\n * [Read the documentation for `P.bigint.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween)\n *\n * @example\n * match(value)\n * .with(P.bigint.between(0, 10), () => '0 <= bigints <= 10')\n */\nconst betweenBigInt = <\n input,\n const min extends bigint,\n const max extends bigint\n>(\n min: min,\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && min <= value && max >= value);\n\n/**\n * `P.bigint.lt(max)` matches **bigint** smaller than `max`.\n *\n * [Read the documentation for `P.bigint.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt)\n *\n * @example\n * match(value)\n * .with(P.bigint.lt(10), () => 'bigints < 10')\n */\nconst ltBigInt = (\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value < max);\n\n/**\n * `P.bigint.gt(min)` matches **bigint** greater than `min`.\n *\n * [Read the documentation for `P.bigint.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt)\n *\n * @example\n * match(value)\n * .with(P.bigint.gt(10), () => 'bigints > 10')\n */\nconst gtBigInt = (\n min: min\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value > min);\n\n/**\n * `P.bigint.lte(max)` matches **bigint** smaller than or equal to `max`.\n *\n * [Read the documentation for `P.bigint.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte)\n *\n * @example\n * match(value)\n * .with(P.bigint.lte(10), () => 'bigints <= 10')\n */\nconst lteBigInt = (\n max: max\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value <= max);\n\n/**\n * `P.bigint.gte(min)` matches **bigint** greater than or equal to `min`.\n *\n * [Read the documentation for `P.bigint.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintgte)\n *\n * @example\n * match(value)\n * .with(P.bigint.gte(10), () => 'bigints >= 10')\n */\nconst gteBigInt = (\n min: min\n): GuardExcludeP =>\n when((value) => isBigInt(value) && value >= min);\n\n/**\n * `P.bigint.positive()` matches **positive** bigints.\n *\n * [Read the documentation for `P.bigint.positive()` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintpositive)\n *\n * @example\n * match(value)\n * .with(P.bigint.positive(), () => 'bigint > 0')\n */\nconst positiveBigInt = (): GuardExcludeP =>\n when((value) => isBigInt(value) && value > 0);\n\n/**\n * `P.bigint.negative()` matches **negative** bigints.\n *\n * [Read the documentation for `P.bigint.negative()` on GitHub](https://github.com/gvergnaud/ts-pattern#pbigintnegative)\n *\n * @example\n * match(value)\n * .with(P.bigint.negative(), () => 'bigint < 0')\n */\nconst negativeBigInt = (): GuardExcludeP =>\n when((value) => isBigInt(value) && value < 0);\n\nconst bigintChainable = >(\n pattern: pattern\n): BigIntChainable =>\n Object.assign(chainable(pattern), {\n between: (min: bigint, max: bigint) =>\n bigintChainable(intersection(pattern, betweenBigInt(min, max))),\n lt: (max: bigint) => bigintChainable(intersection(pattern, ltBigInt(max))),\n gt: (min: bigint) => bigintChainable(intersection(pattern, gtBigInt(min))),\n lte: (max: bigint) =>\n bigintChainable(intersection(pattern, lteBigInt(max))),\n gte: (min: bigint) =>\n bigintChainable(intersection(pattern, gteBigInt(min))),\n positive: () => bigintChainable(intersection(pattern, positiveBigInt())),\n negative: () => bigintChainable(intersection(pattern, negativeBigInt())),\n }) as any;\n\n/**\n * `P.bigint` is a wildcard pattern, matching any **bigint**.\n *\n * [Read the documentation for `P.bigint` on GitHub](https://github.com/gvergnaud/ts-pattern#number-wildcard)\n *\n * @example\n * .with(P.bigint, () => 'will match on bigints')\n */\nexport const bigint: BigIntPattern = bigintChainable(when(isBigInt));\n\n/**\n * `P.boolean` is a wildcard pattern, matching any **boolean**.\n *\n * [Read the documentation for `P.boolean` on GitHub](https://github.com/gvergnaud/ts-pattern#boolean-wildcard)\n *\n * @example\n * .with(P.boolean, () => 'will match on booleans')\n */\nexport const boolean: BooleanPattern = chainable(when(isBoolean));\n\n/**\n * `P.symbol` is a wildcard pattern, matching any **symbol**.\n *\n * [Read the documentation for `P.symbol` on GitHub](https://github.com/gvergnaud/ts-pattern#symbol-wildcard)\n *\n * @example\n * .with(P.symbol, () => 'will match on symbols')\n */\nexport const symbol: SymbolPattern = chainable(when(isSymbol));\n\n/**\n * `P.nullish` is a wildcard pattern, matching **null** or **undefined**.\n *\n * [Read the documentation for `P.nullish` on GitHub](https://github.com/gvergnaud/ts-pattern#nullish-wildcard)\n *\n * @example\n * .with(P.nullish, (x) => `${x} is null or undefined`)\n */\nexport const nullish: NullishPattern = chainable(when(isNullish));\n\n/**\n * `P.nonNullable` is a wildcard pattern, matching everything except **null** or **undefined**.\n *\n * [Read the documentation for `P.nonNullable` on GitHub](https://github.com/gvergnaud/ts-pattern#nonNullable-wildcard)\n *\n * @example\n * .with(P.nonNullable, (x) => `${x} isn't null nor undefined`)\n */\nexport const nonNullable: NonNullablePattern = chainable(when(isNonNullable));\n\n/**\n * `P.instanceOf(SomeClass)` is a pattern matching instances of a given class.\n *\n * [Read the documentation for `P.instanceOf` on GitHub](https://github.com/gvergnaud/ts-pattern#pinstanceof-patterns)\n *\n * @example\n * .with(P.instanceOf(SomeClass), () => 'will match on SomeClass instances')\n */\nexport function instanceOf(\n classConstructor: T\n): Chainable>> {\n return chainable(when(isInstanceOf(classConstructor)));\n}\n\n/**\n * `P.shape(somePattern)` lets you call methods like `.optional()`, `.and`, `.or` and `.select()`\n * On structural patterns, like objects and arrays.\n *\n * [Read the documentation for `P.shape` on GitHub](https://github.com/gvergnaud/ts-pattern#pshape-patterns)\n *\n * @example\n * .with(\n * {\n * state: P.shape({ status: \"success\" }).optional().select()\n * },\n * (state) => 'match the success state, or undefined.'\n * )\n */\nexport function shape>(\n pattern: pattern\n): Chainable>>;\nexport function shape(pattern: UnknownPattern) {\n return chainable(when(isMatching(pattern)));\n}\n","/**\n * Error when the given input value does not match any included pattern\n * and .exhaustive() was specified\n */\nexport class NonExhaustiveError extends Error {\n constructor(public input: unknown) {\n let displayedValue;\n try {\n displayedValue = JSON.stringify(input);\n } catch (e) {\n displayedValue = input;\n }\n super(`Pattern matching error: no pattern matches value ${displayedValue}`);\n }\n}\n","import { Pattern } from './types/Pattern';\nimport { Match } from './types/Match';\nimport * as symbols from './internals/symbols';\nimport { matchPattern } from './internals/helpers';\nimport { NonExhaustiveError } from './errors';\n\ntype MatchState =\n | { matched: true; value: output }\n | { matched: false; value: undefined };\n\nconst unmatched: MatchState = {\n matched: false,\n value: undefined,\n};\n\n/**\n * `match` creates a **pattern matching expression**.\n * * Use `.with(pattern, handler)` to pattern match on the input.\n * * Use `.exhaustive()` or `.otherwise(() => defaultValue)` to end the expression and get the result.\n *\n * [Read the documentation for `match` on GitHub](https://github.com/gvergnaud/ts-pattern#match)\n *\n * @example\n * declare let input: \"A\" | \"B\";\n *\n * return match(input)\n * .with(\"A\", () => \"It's an A!\")\n * .with(\"B\", () => \"It's a B!\")\n * .exhaustive();\n *\n */\nexport function match(\n value: input\n): Match {\n return new MatchExpression(value, unmatched) as any;\n}\n\n/**\n * This class represents a match expression. It follows the\n * builder pattern, we chain methods to add features to the expression\n * until we call `.exhaustive`, `.otherwise` or the unsafe `.run`\n * method to execute it.\n *\n * The types of this class aren't public, the public type definition\n * can be found in src/types/Match.ts.\n */\nclass MatchExpression {\n constructor(private input: input, private state: MatchState) {}\n\n with(...args: any[]): MatchExpression {\n if (this.state.matched) return this;\n\n const handler: (selection: unknown, value: input) => output =\n args[args.length - 1];\n\n const patterns: Pattern[] = [args[0]];\n let predicate: ((value: input) => unknown) | undefined = undefined;\n\n if (args.length === 3 && typeof args[1] === 'function') {\n // case with guard as second argument\n predicate = args[1];\n } else if (args.length > 2) {\n // case with several patterns\n patterns.push(...args.slice(1, args.length - 1));\n }\n\n let hasSelections = false;\n let selected: Record = {};\n const select = (key: string, value: unknown) => {\n hasSelections = true;\n selected[key] = value;\n };\n\n const matched =\n patterns.some((pattern) => matchPattern(pattern, this.input, select)) &&\n (predicate ? Boolean(predicate(this.input)) : true);\n\n const selections = hasSelections\n ? symbols.anonymousSelectKey in selected\n ? selected[symbols.anonymousSelectKey]\n : selected\n : this.input;\n\n const state = matched\n ? {\n matched: true as const,\n value: handler(selections, this.input),\n }\n : unmatched;\n\n return new MatchExpression(this.input, state);\n }\n\n when(\n predicate: (value: input) => unknown,\n handler: (selection: input, value: input) => output\n ): MatchExpression {\n if (this.state.matched) return this;\n\n const matched = Boolean(predicate(this.input));\n\n return new MatchExpression(\n this.input,\n matched\n ? { matched: true, value: handler(this.input, this.input) }\n : unmatched\n );\n }\n\n otherwise(handler: (value: input) => output): output {\n if (this.state.matched) return this.state.value;\n return handler(this.input);\n }\n\n exhaustive(): output {\n if (this.state.matched) return this.state.value;\n\n throw new NonExhaustiveError(this.input);\n }\n\n run(): output {\n return this.exhaustive();\n }\n\n returnType() {\n return this;\n }\n}\n"],"names":["matcher","Symbol","isVariadic","anonymousSelectKey","isObject","value","Boolean","isMatcher","x","symbols","matchPattern","pattern","select","_matcher$match","match","matched","selections","Object","keys","forEach","key","Array","isArray","_step","startPatterns","endPatterns","variadicPatterns","_iterator","_createForOfIteratorHelperLoose","done","subpattern","push","length","Error","startValues","slice","endValues","middleValues","Infinity","every","subPattern","i","Reflect","ownKeys","k","matcherType","is","getSelectionKeys","_pattern$symbols$matc","_pattern$symbols$matc2","_pattern$symbols$matc3","call","flatMap","values","xs","f","reduce","acc","concat","isMatching","args","arguments","chainable","assign","optional","and","p2","intersection","or","union","undefined","arrayChainable","_Object$assign2","iterator","_Object$assign","next","_values$i","at","variadic","_chainable","selector","setEvery","set","predicate","mapEvery","map","_step2","_iterator2","entries","_step2$value","_chainable4","patterns","p","_chainable5","some","when","_ref","_chainable7","_selections","isNumber","isString","isBigInt","any","_","string","stringChainable","startsWith","str","start","endsWith","end","minLength","min","len","maxLength","max","includes","substr","regex","expr","number","numberChainable","between","lt","gt","lte","gte","int","Number","isInteger","finite","isFinite","positive","negative","bigint","bigintChainable","betweenBigInt","ltBigInt","gtBigInt","lteBigInt","gteBigInt","boolean","symbol","nullish","nonNullable","_arrayChainable","v","_chainable2","Set","size","_chainable3","Map","_args$","toString","patternKey","patternValue","keyMatch","valueMatch","_chainable6","classConstructor","val","isInstanceOf","NonExhaustiveError","_Error","input","_this","displayedValue","JSON","stringify","e","this","_wrapNativeSuper","unmatched","MatchExpression","state","_proto","prototype","handler","apply","hasSelections","selected","otherwise","exhaustive","run","returnType"],"mappings":"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"} \ No newline at end of file diff --git a/dist/internals/helpers.d.cts b/dist/internals/helpers.d.cts new file mode 100644 index 00000000..094a43fe --- /dev/null +++ b/dist/internals/helpers.d.cts @@ -0,0 +1,12 @@ +/** + * @module + * @private + * @internal + */ +import { SelectionType } from '../types/FindSelected.cjs'; +import { Matcher, MatcherType } from '../types/Pattern.cjs'; +export declare const isObject: (value: unknown) => value is Object; +export declare const isMatcher: (x: unknown) => x is Matcher; +export declare const matchPattern: (pattern: any, value: any, select: (key: string, value: unknown) => void) => boolean; +export declare const getSelectionKeys: (pattern: any) => string[]; +export declare const flatMap: (xs: readonly a[], f: (v: a) => readonly b[]) => b[]; diff --git a/dist/internals/helpers.d.ts b/dist/internals/helpers.d.ts new file mode 100644 index 00000000..1c6fc95a --- /dev/null +++ b/dist/internals/helpers.d.ts @@ -0,0 +1,12 @@ +/** + * @module + * @private + * @internal + */ +import { SelectionType } from '../types/FindSelected.js'; +import { Matcher, MatcherType } from '../types/Pattern.js'; +export declare const isObject: (value: unknown) => value is Object; +export declare const isMatcher: (x: unknown) => x is Matcher; +export declare const matchPattern: (pattern: any, value: any, select: (key: string, value: unknown) => void) => boolean; +export declare const getSelectionKeys: (pattern: any) => string[]; +export declare const flatMap: (xs: readonly a[], f: (v: a) => readonly b[]) => b[]; diff --git a/dist/internals/symbols.d.cts b/dist/internals/symbols.d.cts new file mode 100644 index 00000000..98baceca --- /dev/null +++ b/dist/internals/symbols.d.cts @@ -0,0 +1,24 @@ +/** + * Symbols used internally within ts-pattern to construct and discriminate + * Guard, Not, and Select, and AnonymousSelect patterns + * + * Symbols have the advantage of not appearing in auto-complete suggestions in + * user defined patterns, and eliminate the risk of property + * overlap between ts-pattern internals and user defined patterns. + * + * These symbols have to be visible to tsc for type inference to work, but + * users should not import them + * @module + * @private + * @internal + */ +export declare const matcher: unique symbol; +export type matcher = typeof matcher; +export declare const unset: unique symbol; +export type unset = typeof unset; +export declare const isVariadic: unique symbol; +export type isVariadic = typeof isVariadic; +export declare const anonymousSelectKey = "@ts-pattern/anonymous-select-key"; +export type anonymousSelectKey = typeof anonymousSelectKey; +export declare const override: unique symbol; +export type override = typeof override; diff --git a/dist/internals/symbols.d.ts b/dist/internals/symbols.d.ts new file mode 100644 index 00000000..98baceca --- /dev/null +++ b/dist/internals/symbols.d.ts @@ -0,0 +1,24 @@ +/** + * Symbols used internally within ts-pattern to construct and discriminate + * Guard, Not, and Select, and AnonymousSelect patterns + * + * Symbols have the advantage of not appearing in auto-complete suggestions in + * user defined patterns, and eliminate the risk of property + * overlap between ts-pattern internals and user defined patterns. + * + * These symbols have to be visible to tsc for type inference to work, but + * users should not import them + * @module + * @private + * @internal + */ +export declare const matcher: unique symbol; +export type matcher = typeof matcher; +export declare const unset: unique symbol; +export type unset = typeof unset; +export declare const isVariadic: unique symbol; +export type isVariadic = typeof isVariadic; +export declare const anonymousSelectKey = "@ts-pattern/anonymous-select-key"; +export type anonymousSelectKey = typeof anonymousSelectKey; +export declare const override: unique symbol; +export type override = typeof override; diff --git a/dist/is-matching.d.cts b/dist/is-matching.d.cts new file mode 100644 index 00000000..2b0dbebf --- /dev/null +++ b/dist/is-matching.d.cts @@ -0,0 +1,32 @@ +import { Pattern } from './types/Pattern.cjs'; +import * as P from './patterns.cjs'; +/** + * `isMatching` takes pattern and returns a **type guard** function, cheching if a value matches this pattern. + * + * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching) + * + * @example + * const hasName = isMatching({ name: P.string }) + * + * declare let input: unknown + * + * if (hasName(input)) { + * // `input` inferred as { name: string } + * return input.name + * } + */ +export declare function isMatching>(pattern: p): (value: unknown) => value is P.infer

; +/** + * `isMatching` takes pattern and a value and checks if the value matches this pattern. + * + * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching) + * + * @example + * declare let input: unknown + * + * if (isMatching({ name: P.string }, input)) { + * // `input` inferred as { name: string } + * return input.name + * } + */ +export declare function isMatching>(pattern: p, value: unknown): value is P.infer

; diff --git a/dist/is-matching.d.ts b/dist/is-matching.d.ts new file mode 100644 index 00000000..e2161fe9 --- /dev/null +++ b/dist/is-matching.d.ts @@ -0,0 +1,32 @@ +import { Pattern } from './types/Pattern.js'; +import * as P from './patterns.js'; +/** + * `isMatching` takes pattern and returns a **type guard** function, cheching if a value matches this pattern. + * + * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching) + * + * @example + * const hasName = isMatching({ name: P.string }) + * + * declare let input: unknown + * + * if (hasName(input)) { + * // `input` inferred as { name: string } + * return input.name + * } + */ +export declare function isMatching>(pattern: p): (value: unknown) => value is P.infer

; +/** + * `isMatching` takes pattern and a value and checks if the value matches this pattern. + * + * [Read documentation for `isMatching` on GitHub](https://github.com/gvergnaud/ts-pattern#ismatching) + * + * @example + * declare let input: unknown + * + * if (isMatching({ name: P.string }, input)) { + * // `input` inferred as { name: string } + * return input.name + * } + */ +export declare function isMatching>(pattern: p, value: unknown): value is P.infer

; diff --git a/dist/match.d.cts b/dist/match.d.cts new file mode 100644 index 00000000..d3e6d5bf --- /dev/null +++ b/dist/match.d.cts @@ -0,0 +1,19 @@ +import { Match } from './types/Match.cjs'; +import * as symbols from './internals/symbols.cjs'; +/** + * `match` creates a **pattern matching expression**. + * * Use `.with(pattern, handler)` to pattern match on the input. + * * Use `.exhaustive()` or `.otherwise(() => defaultValue)` to end the expression and get the result. + * + * [Read the documentation for `match` on GitHub](https://github.com/gvergnaud/ts-pattern#match) + * + * @example + * declare let input: "A" | "B"; + * + * return match(input) + * .with("A", () => "It's an A!") + * .with("B", () => "It's a B!") + * .exhaustive(); + * + */ +export declare function match(value: input): Match; diff --git a/dist/match.d.ts b/dist/match.d.ts new file mode 100644 index 00000000..b3bdfb03 --- /dev/null +++ b/dist/match.d.ts @@ -0,0 +1,19 @@ +import { Match } from './types/Match.js'; +import * as symbols from './internals/symbols.js'; +/** + * `match` creates a **pattern matching expression**. + * * Use `.with(pattern, handler)` to pattern match on the input. + * * Use `.exhaustive()` or `.otherwise(() => defaultValue)` to end the expression and get the result. + * + * [Read the documentation for `match` on GitHub](https://github.com/gvergnaud/ts-pattern#match) + * + * @example + * declare let input: "A" | "B"; + * + * return match(input) + * .with("A", () => "It's an A!") + * .with("B", () => "It's a B!") + * .exhaustive(); + * + */ +export declare function match(value: input): Match; diff --git a/dist/patterns.d.cts b/dist/patterns.d.cts new file mode 100644 index 00000000..06d05d3e --- /dev/null +++ b/dist/patterns.d.cts @@ -0,0 +1,302 @@ +import * as symbols from './internals/symbols.cjs'; +import { matcher } from './internals/symbols.cjs'; +import { ExtractPreciseValue } from './types/ExtractPreciseValue.cjs'; +import { Fn } from './types/helpers.cjs'; +import { InvertPattern } from './types/InvertPattern.cjs'; +import { Pattern, UnknownPattern, OptionalP, ArrayP, MapP, SetP, AndP, OrP, NotP, GuardP, SelectP, AnonymousSelectP, GuardExcludeP, CustomP, StringPattern, AnyPattern, NumberPattern, BooleanPattern, BigIntPattern, NullishPattern, SymbolPattern, Chainable, ArrayChainable, NonNullablePattern } from './types/Pattern.cjs'; +export type { Pattern, Fn as unstable_Fn }; +export { matcher }; +/** + * @experimental + * A `Matchable` is an object implementing + * the Matcher Protocol. It must have a `[P.matcher]: P.Matcher` + * key, which defines how this object should be matched by TS-Pattern. + * + * Note that this api is unstable. + * + * @example + * ```ts + * class Some implements P.unstable_Matchable { + * [P.matcher](): P.unstable_Matcher> + * } + * ``` + */ +export type unstable_Matchable = CustomP; +/** + * @experimental + * A `Matcher` is an object with `match` function, which + * defines how this object should be matched by TS-Pattern. + * + * Note that this api is unstable. + * + * @example + * ```ts + * class Some implements P.unstable_Matchable { + * [P.matcher](): P.unstable_Matcher> + * } + * ``` + */ +export type unstable_Matcher = ReturnType[matcher]>; +/** + * `P.infer` will return the type of the value + * matched by this pattern. + * + * [Read the documentation for `P.infer` on GitHub](https://github.com/gvergnaud/ts-pattern#pinfer) + * + * @example + * const userPattern = { name: P.string } + * type User = P.infer + */ +export type infer> = InvertPattern; +/** + * `P.narrow` will narrow the input type to only keep + * the set of values that are compatible with the provided pattern type. + * + * [Read the documentation for `P.narrow` on GitHub](https://github.com/gvergnaud/ts-pattern#pnarrow) + * + * @example + * type Input = ['a' | 'b' | 'c', 'a' | 'b' | 'c'] + * const Pattern = ['a', P.union('a', 'b')] as const + * + * type Narrowed = P.narrow + * // ^? ['a', 'a' | 'b'] + */ +export type narrow> = ExtractPreciseValue>; +/** + * `P.optional(subpattern)` takes a sub pattern and returns a pattern which matches if the + * key is undefined or if it is defined and the sub pattern matches its value. + * + * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns) + * + * @example + * match(value) + * .with({ greeting: P.optional('Hello') }, () => 'will match { greeting?: "Hello" }') + */ +export declare function optional>(pattern: pattern): Chainable, 'optional'>; +type UnwrapArray = xs extends readonly (infer x)[] ? x : never; +type UnwrapSet = xs extends Set ? x : never; +type UnwrapMapKey = xs extends Map ? k : never; +type UnwrapMapValue = xs extends Map ? v : never; +type WithDefault = [a] extends [never] ? b : a; +/** + * `P.array(subpattern)` takes a sub pattern and returns a pattern, which matches + * arrays if all their elements match the sub pattern. + * + * [Read the documentation for `P.array` on GitHub](https://github.com/gvergnaud/ts-pattern#parray-patterns) + * + * @example + * match(value) + * .with({ users: P.array({ name: P.string }) }, () => 'will match { name: string }[]') + */ +export declare function array(): ArrayChainable>; +export declare function array, unknown>>>(pattern: pattern): ArrayChainable>; +/** + * `P.set(subpattern)` takes a sub pattern and returns a pattern that matches + * sets if all their elements match the sub pattern. + * + * [Read `P.set` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pset-patterns) + * + * @example + * match(value) + * .with({ users: P.set(P.string) }, () => 'will match Set') + */ +export declare function set(): Chainable>; +export declare function set, unknown>>>(pattern: pattern): Chainable>; +/** + * `P.map(keyPattern, valuePattern)` takes a subpattern to match against the + * key, a subpattern to match against the value and returns a pattern that + * matches on maps where all elements inside the map match those two + * subpatterns. + * + * [Read `P.map` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pmap-patterns) + * + * @example + * match(value) + * .with({ users: P.map(P.map(P.string, P.number)) }, (map) => `map's type is Map`) + */ +export declare function map(): Chainable>; +export declare function map, unknown>>, const pvalue extends Pattern, unknown>>>(patternKey: pkey, patternValue: pvalue): Chainable>; +/** + * `P.intersection(...patterns)` returns a pattern which matches + * only if **every** patterns provided in parameter match the input. + * + * [Read the documentation for `P.intersection` on GitHub](https://github.com/gvergnaud/ts-pattern#pintersection-patterns) + * + * @example + * match(value) + * .with( + * { + * user: P.intersection( + * { firstname: P.string }, + * { lastname: P.string }, + * { age: P.when(age => age > 21) } + * ) + * }, + * ({ user }) => 'will match { firstname: string, lastname: string, age: number } if age > 21' + * ) + */ +export declare function intersection, ...Pattern[]]>(...patterns: patterns): Chainable>; +/** + * `P.union(...patterns)` returns a pattern which matches + * if **at least one** of the patterns provided in parameter match the input. + * + * [Read the documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#punion-patterns) + * + * @example + * match(value) + * .with( + * { type: P.union('a', 'b', 'c') }, + * ({ type }) => 'will match { type: "a" | "b" | "c" }' + * ) + */ +export declare function union, ...Pattern[]]>(...patterns: patterns): Chainable>; +/** + * `P.not(pattern)` returns a pattern which matches if the sub pattern + * doesn't match. + * + * [Read the documentation for `P.not` on GitHub](https://github.com/gvergnaud/ts-pattern#pnot-patterns) + * + * @example + * match<{ a: string | number }>(value) + * .with({ a: P.not(P.string) }, (x) => 'will match { a: number }' + * ) + */ +export declare function not | UnknownPattern>(pattern: pattern): Chainable>; +/** + * `P.when((value) => boolean)` returns a pattern which matches + * if the predicate returns true for the current input. + * + * [Read the documentation for `P.when` on GitHub](https://github.com/gvergnaud/ts-pattern#pwhen-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.when(age => age > 21) }, (x) => 'will match if value.age > 21' + * ) + */ +export declare function when unknown>(predicate: predicate): GuardP value is infer narrowed ? narrowed : never>; +export declare function when(predicate: (input: input) => input is narrowed): GuardExcludeP; +/** + * `P.select()` is a pattern which will always match, + * and will inject the selected piece of input in the handler function. + * + * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.select() }, (age) => 'age: number' + * ) + */ +export declare function select(): Chainable; +export declare function select)>(patternOrKey: patternOrKey): patternOrKey extends string ? Chainable> : Chainable, 'select' | 'or' | 'and'>; +export declare function select, const k extends string>(key: k, pattern: pattern): Chainable, 'select' | 'or' | 'and'>; +type AnyConstructor = abstract new (...args: any[]) => any; +/** + * `P.any` is a wildcard pattern, matching **any value**. + * + * [Read the documentation for `P.any` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard) + * + * @example + * match(value) + * .with(P.any, () => 'will always match') + */ +export declare const any: AnyPattern; +/** + * `P._` is a wildcard pattern, matching **any value**. + * It's an alias to `P.any`. + * + * [Read the documentation for `P._` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard) + * + * @example + * match(value) + * .with(P._, () => 'will always match') + */ +export declare const _: AnyPattern; +/** + * `P.string` is a wildcard pattern, matching any **string**. + * + * [Read the documentation for `P.string` on GitHub](https://github.com/gvergnaud/ts-pattern#pstring-wildcard) + * + * @example + * match(value) + * .with(P.string, () => 'will match on strings') + */ +export declare const string: StringPattern; +/** + * `P.number` is a wildcard pattern, matching any **number**. + * + * [Read the documentation for `P.number` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumber-wildcard) + * + * @example + * match(value) + * .with(P.number, () => 'will match on numbers') + */ +export declare const number: NumberPattern; +/** + * `P.bigint` is a wildcard pattern, matching any **bigint**. + * + * [Read the documentation for `P.bigint` on GitHub](https://github.com/gvergnaud/ts-pattern#number-wildcard) + * + * @example + * .with(P.bigint, () => 'will match on bigints') + */ +export declare const bigint: BigIntPattern; +/** + * `P.boolean` is a wildcard pattern, matching any **boolean**. + * + * [Read the documentation for `P.boolean` on GitHub](https://github.com/gvergnaud/ts-pattern#boolean-wildcard) + * + * @example + * .with(P.boolean, () => 'will match on booleans') + */ +export declare const boolean: BooleanPattern; +/** + * `P.symbol` is a wildcard pattern, matching any **symbol**. + * + * [Read the documentation for `P.symbol` on GitHub](https://github.com/gvergnaud/ts-pattern#symbol-wildcard) + * + * @example + * .with(P.symbol, () => 'will match on symbols') + */ +export declare const symbol: SymbolPattern; +/** + * `P.nullish` is a wildcard pattern, matching **null** or **undefined**. + * + * [Read the documentation for `P.nullish` on GitHub](https://github.com/gvergnaud/ts-pattern#nullish-wildcard) + * + * @example + * .with(P.nullish, (x) => `${x} is null or undefined`) + */ +export declare const nullish: NullishPattern; +/** + * `P.nonNullable` is a wildcard pattern, matching everything except **null** or **undefined**. + * + * [Read the documentation for `P.nonNullable` on GitHub](https://github.com/gvergnaud/ts-pattern#nonNullable-wildcard) + * + * @example + * .with(P.nonNullable, (x) => `${x} isn't null nor undefined`) + */ +export declare const nonNullable: NonNullablePattern; +/** + * `P.instanceOf(SomeClass)` is a pattern matching instances of a given class. + * + * [Read the documentation for `P.instanceOf` on GitHub](https://github.com/gvergnaud/ts-pattern#pinstanceof-patterns) + * + * @example + * .with(P.instanceOf(SomeClass), () => 'will match on SomeClass instances') + */ +export declare function instanceOf(classConstructor: T): Chainable>>; +/** + * `P.shape(somePattern)` lets you call methods like `.optional()`, `.and`, `.or` and `.select()` + * On structural patterns, like objects and arrays. + * + * [Read the documentation for `P.shape` on GitHub](https://github.com/gvergnaud/ts-pattern#pshape-patterns) + * + * @example + * .with( + * { + * state: P.shape({ status: "success" }).optional().select() + * }, + * (state) => 'match the success state, or undefined.' + * ) + */ +export declare function shape>(pattern: pattern): Chainable>>; diff --git a/dist/patterns.d.ts b/dist/patterns.d.ts new file mode 100644 index 00000000..808bf7ef --- /dev/null +++ b/dist/patterns.d.ts @@ -0,0 +1,302 @@ +import * as symbols from './internals/symbols.js'; +import { matcher } from './internals/symbols.js'; +import { ExtractPreciseValue } from './types/ExtractPreciseValue.js'; +import { Fn } from './types/helpers.js'; +import { InvertPattern } from './types/InvertPattern.js'; +import { Pattern, UnknownPattern, OptionalP, ArrayP, MapP, SetP, AndP, OrP, NotP, GuardP, SelectP, AnonymousSelectP, GuardExcludeP, CustomP, StringPattern, AnyPattern, NumberPattern, BooleanPattern, BigIntPattern, NullishPattern, SymbolPattern, Chainable, ArrayChainable, NonNullablePattern } from './types/Pattern.js'; +export type { Pattern, Fn as unstable_Fn }; +export { matcher }; +/** + * @experimental + * A `Matchable` is an object implementing + * the Matcher Protocol. It must have a `[P.matcher]: P.Matcher` + * key, which defines how this object should be matched by TS-Pattern. + * + * Note that this api is unstable. + * + * @example + * ```ts + * class Some implements P.unstable_Matchable { + * [P.matcher](): P.unstable_Matcher> + * } + * ``` + */ +export type unstable_Matchable = CustomP; +/** + * @experimental + * A `Matcher` is an object with `match` function, which + * defines how this object should be matched by TS-Pattern. + * + * Note that this api is unstable. + * + * @example + * ```ts + * class Some implements P.unstable_Matchable { + * [P.matcher](): P.unstable_Matcher> + * } + * ``` + */ +export type unstable_Matcher = ReturnType[matcher]>; +/** + * `P.infer` will return the type of the value + * matched by this pattern. + * + * [Read the documentation for `P.infer` on GitHub](https://github.com/gvergnaud/ts-pattern#pinfer) + * + * @example + * const userPattern = { name: P.string } + * type User = P.infer + */ +export type infer> = InvertPattern; +/** + * `P.narrow` will narrow the input type to only keep + * the set of values that are compatible with the provided pattern type. + * + * [Read the documentation for `P.narrow` on GitHub](https://github.com/gvergnaud/ts-pattern#pnarrow) + * + * @example + * type Input = ['a' | 'b' | 'c', 'a' | 'b' | 'c'] + * const Pattern = ['a', P.union('a', 'b')] as const + * + * type Narrowed = P.narrow + * // ^? ['a', 'a' | 'b'] + */ +export type narrow> = ExtractPreciseValue>; +/** + * `P.optional(subpattern)` takes a sub pattern and returns a pattern which matches if the + * key is undefined or if it is defined and the sub pattern matches its value. + * + * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns) + * + * @example + * match(value) + * .with({ greeting: P.optional('Hello') }, () => 'will match { greeting?: "Hello" }') + */ +export declare function optional>(pattern: pattern): Chainable, 'optional'>; +type UnwrapArray = xs extends readonly (infer x)[] ? x : never; +type UnwrapSet = xs extends Set ? x : never; +type UnwrapMapKey = xs extends Map ? k : never; +type UnwrapMapValue = xs extends Map ? v : never; +type WithDefault = [a] extends [never] ? b : a; +/** + * `P.array(subpattern)` takes a sub pattern and returns a pattern, which matches + * arrays if all their elements match the sub pattern. + * + * [Read the documentation for `P.array` on GitHub](https://github.com/gvergnaud/ts-pattern#parray-patterns) + * + * @example + * match(value) + * .with({ users: P.array({ name: P.string }) }, () => 'will match { name: string }[]') + */ +export declare function array(): ArrayChainable>; +export declare function array, unknown>>>(pattern: pattern): ArrayChainable>; +/** + * `P.set(subpattern)` takes a sub pattern and returns a pattern that matches + * sets if all their elements match the sub pattern. + * + * [Read `P.set` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pset-patterns) + * + * @example + * match(value) + * .with({ users: P.set(P.string) }, () => 'will match Set') + */ +export declare function set(): Chainable>; +export declare function set, unknown>>>(pattern: pattern): Chainable>; +/** + * `P.map(keyPattern, valuePattern)` takes a subpattern to match against the + * key, a subpattern to match against the value and returns a pattern that + * matches on maps where all elements inside the map match those two + * subpatterns. + * + * [Read `P.map` documentation on GitHub](https://github.com/gvergnaud/ts-pattern#pmap-patterns) + * + * @example + * match(value) + * .with({ users: P.map(P.map(P.string, P.number)) }, (map) => `map's type is Map`) + */ +export declare function map(): Chainable>; +export declare function map, unknown>>, const pvalue extends Pattern, unknown>>>(patternKey: pkey, patternValue: pvalue): Chainable>; +/** + * `P.intersection(...patterns)` returns a pattern which matches + * only if **every** patterns provided in parameter match the input. + * + * [Read the documentation for `P.intersection` on GitHub](https://github.com/gvergnaud/ts-pattern#pintersection-patterns) + * + * @example + * match(value) + * .with( + * { + * user: P.intersection( + * { firstname: P.string }, + * { lastname: P.string }, + * { age: P.when(age => age > 21) } + * ) + * }, + * ({ user }) => 'will match { firstname: string, lastname: string, age: number } if age > 21' + * ) + */ +export declare function intersection, ...Pattern[]]>(...patterns: patterns): Chainable>; +/** + * `P.union(...patterns)` returns a pattern which matches + * if **at least one** of the patterns provided in parameter match the input. + * + * [Read the documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#punion-patterns) + * + * @example + * match(value) + * .with( + * { type: P.union('a', 'b', 'c') }, + * ({ type }) => 'will match { type: "a" | "b" | "c" }' + * ) + */ +export declare function union, ...Pattern[]]>(...patterns: patterns): Chainable>; +/** + * `P.not(pattern)` returns a pattern which matches if the sub pattern + * doesn't match. + * + * [Read the documentation for `P.not` on GitHub](https://github.com/gvergnaud/ts-pattern#pnot-patterns) + * + * @example + * match<{ a: string | number }>(value) + * .with({ a: P.not(P.string) }, (x) => 'will match { a: number }' + * ) + */ +export declare function not | UnknownPattern>(pattern: pattern): Chainable>; +/** + * `P.when((value) => boolean)` returns a pattern which matches + * if the predicate returns true for the current input. + * + * [Read the documentation for `P.when` on GitHub](https://github.com/gvergnaud/ts-pattern#pwhen-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.when(age => age > 21) }, (x) => 'will match if value.age > 21' + * ) + */ +export declare function when unknown>(predicate: predicate): GuardP value is infer narrowed ? narrowed : never>; +export declare function when(predicate: (input: input) => input is narrowed): GuardExcludeP; +/** + * `P.select()` is a pattern which will always match, + * and will inject the selected piece of input in the handler function. + * + * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.select() }, (age) => 'age: number' + * ) + */ +export declare function select(): Chainable; +export declare function select)>(patternOrKey: patternOrKey): patternOrKey extends string ? Chainable> : Chainable, 'select' | 'or' | 'and'>; +export declare function select, const k extends string>(key: k, pattern: pattern): Chainable, 'select' | 'or' | 'and'>; +type AnyConstructor = abstract new (...args: any[]) => any; +/** + * `P.any` is a wildcard pattern, matching **any value**. + * + * [Read the documentation for `P.any` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard) + * + * @example + * match(value) + * .with(P.any, () => 'will always match') + */ +export declare const any: AnyPattern; +/** + * `P._` is a wildcard pattern, matching **any value**. + * It's an alias to `P.any`. + * + * [Read the documentation for `P._` on GitHub](https://github.com/gvergnaud/ts-pattern#p_-wildcard) + * + * @example + * match(value) + * .with(P._, () => 'will always match') + */ +export declare const _: AnyPattern; +/** + * `P.string` is a wildcard pattern, matching any **string**. + * + * [Read the documentation for `P.string` on GitHub](https://github.com/gvergnaud/ts-pattern#pstring-wildcard) + * + * @example + * match(value) + * .with(P.string, () => 'will match on strings') + */ +export declare const string: StringPattern; +/** + * `P.number` is a wildcard pattern, matching any **number**. + * + * [Read the documentation for `P.number` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumber-wildcard) + * + * @example + * match(value) + * .with(P.number, () => 'will match on numbers') + */ +export declare const number: NumberPattern; +/** + * `P.bigint` is a wildcard pattern, matching any **bigint**. + * + * [Read the documentation for `P.bigint` on GitHub](https://github.com/gvergnaud/ts-pattern#number-wildcard) + * + * @example + * .with(P.bigint, () => 'will match on bigints') + */ +export declare const bigint: BigIntPattern; +/** + * `P.boolean` is a wildcard pattern, matching any **boolean**. + * + * [Read the documentation for `P.boolean` on GitHub](https://github.com/gvergnaud/ts-pattern#boolean-wildcard) + * + * @example + * .with(P.boolean, () => 'will match on booleans') + */ +export declare const boolean: BooleanPattern; +/** + * `P.symbol` is a wildcard pattern, matching any **symbol**. + * + * [Read the documentation for `P.symbol` on GitHub](https://github.com/gvergnaud/ts-pattern#symbol-wildcard) + * + * @example + * .with(P.symbol, () => 'will match on symbols') + */ +export declare const symbol: SymbolPattern; +/** + * `P.nullish` is a wildcard pattern, matching **null** or **undefined**. + * + * [Read the documentation for `P.nullish` on GitHub](https://github.com/gvergnaud/ts-pattern#nullish-wildcard) + * + * @example + * .with(P.nullish, (x) => `${x} is null or undefined`) + */ +export declare const nullish: NullishPattern; +/** + * `P.nonNullable` is a wildcard pattern, matching everything except **null** or **undefined**. + * + * [Read the documentation for `P.nonNullable` on GitHub](https://github.com/gvergnaud/ts-pattern#nonNullable-wildcard) + * + * @example + * .with(P.nonNullable, (x) => `${x} isn't null nor undefined`) + */ +export declare const nonNullable: NonNullablePattern; +/** + * `P.instanceOf(SomeClass)` is a pattern matching instances of a given class. + * + * [Read the documentation for `P.instanceOf` on GitHub](https://github.com/gvergnaud/ts-pattern#pinstanceof-patterns) + * + * @example + * .with(P.instanceOf(SomeClass), () => 'will match on SomeClass instances') + */ +export declare function instanceOf(classConstructor: T): Chainable>>; +/** + * `P.shape(somePattern)` lets you call methods like `.optional()`, `.and`, `.or` and `.select()` + * On structural patterns, like objects and arrays. + * + * [Read the documentation for `P.shape` on GitHub](https://github.com/gvergnaud/ts-pattern#pshape-patterns) + * + * @example + * .with( + * { + * state: P.shape({ status: "success" }).optional().select() + * }, + * (state) => 'match the success state, or undefined.' + * ) + */ +export declare function shape>(pattern: pattern): Chainable>>; diff --git a/dist/types/BuildMany.d.cts b/dist/types/BuildMany.d.cts new file mode 100644 index 00000000..d3a0ebb7 --- /dev/null +++ b/dist/types/BuildMany.d.cts @@ -0,0 +1,16 @@ +import { Iterator, UpdateAt, ValueOf } from './helpers.cjs'; +export type BuildMany = xs extends any ? BuildOne : never; +type BuildOne = xs extends [ + [ + infer value, + infer path + ], + ...infer tail +] ? BuildOne, tail> : data; +export type SetDeep = path extends readonly [ + infer head, + ...infer tail +] ? data extends readonly any[] ? data extends readonly [any, ...any] ? head extends number ? UpdateAt, SetDeep> : never : SetDeep, value, tail>[] : data extends Set ? Set> : data extends Map ? Map> : head extends keyof data ? { + [k in keyof data]-?: k extends head ? SetDeep : data[k]; +} : data : value; +export {}; diff --git a/dist/types/BuildMany.d.ts b/dist/types/BuildMany.d.ts new file mode 100644 index 00000000..4f452e5b --- /dev/null +++ b/dist/types/BuildMany.d.ts @@ -0,0 +1,16 @@ +import { Iterator, UpdateAt, ValueOf } from './helpers.js'; +export type BuildMany = xs extends any ? BuildOne : never; +type BuildOne = xs extends [ + [ + infer value, + infer path + ], + ...infer tail +] ? BuildOne, tail> : data; +export type SetDeep = path extends readonly [ + infer head, + ...infer tail +] ? data extends readonly any[] ? data extends readonly [any, ...any] ? head extends number ? UpdateAt, SetDeep> : never : SetDeep, value, tail>[] : data extends Set ? Set> : data extends Map ? Map> : head extends keyof data ? { + [k in keyof data]-?: k extends head ? SetDeep : data[k]; +} : data : value; +export {}; diff --git a/dist/types/DeepExclude.d.cts b/dist/types/DeepExclude.d.cts new file mode 100644 index 00000000..a0547f03 --- /dev/null +++ b/dist/types/DeepExclude.d.cts @@ -0,0 +1,2 @@ +import { DistributeMatchingUnions } from './DistributeUnions.cjs'; +export type DeepExclude = Exclude, b>; diff --git a/dist/types/DeepExclude.d.ts b/dist/types/DeepExclude.d.ts new file mode 100644 index 00000000..32d784ec --- /dev/null +++ b/dist/types/DeepExclude.d.ts @@ -0,0 +1,2 @@ +import { DistributeMatchingUnions } from './DistributeUnions.js'; +export type DeepExclude = Exclude, b>; diff --git a/dist/types/DistributeUnions.d.cts b/dist/types/DistributeUnions.d.cts new file mode 100644 index 00000000..bce66d21 --- /dev/null +++ b/dist/types/DistributeUnions.d.cts @@ -0,0 +1,111 @@ +import { BuildMany } from './BuildMany.cjs'; +import type { IsAny, Values, Flatten, IsUnion, IsPlainObject, Length, UnionToTuple, IsReadonlyArray, ValueOf, MaybeAddReadonly, IsStrictArray } from './helpers.cjs'; +import { IsMatching } from './IsMatching.cjs'; +/** + * DistributeMatchingUnions takes two arguments: + * - a data structure of type `a` containing unions + * - a pattern `p`, matching this data structure + * and turns it into a union of all possible + * combination of each unions contained in `a` that matches `p`. + * + * It does this in 3 main steps: + * - 1. Find all unions contained in the data structure, that matches `p` + * with `FindUnions`. It returns a tree of [union, path] pairs. + * - 2. this tree is passed to the `Distribute` type level function, + * Which turns it into a union of list of `[singleValue, path]` pairs. + * Each list correspond to one of the possible combination of the unions + * found in `a`. + * - 3. build a data structure with the same shape as `a` for each combination + * and return the union of these data structures. + * + * @example + * type t1 = DistributeMatchingUnions<['a' | 'b', 1 | 2], ['a', 1]>; + * // => ['a', 1] | ['a', 2] | ['b', 1] | ['b', 2] + * + * type t2 = DistributeMatchingUnions<['a' | 'b', 1 | 2], ['a', unknown]>; + * // => ['a', 1 | 2] | ['b', 1 | 2] + */ +export type DistributeMatchingUnions = IsAny extends true ? any : BuildMany>>; +export type FindUnionsMany = UnionToTuple<(p extends any ? IsMatching extends true ? FindUnions : [] : never) extends readonly (infer T)[] ? T : never>; +/** + * The reason we don't look further down the tree with lists, + * Set and Maps is that they can be heterogeneous, + * so matching on a A[] for a in input of (A|B)[] + * doesn't rule anything out. You can still have + * a (A|B)[] afterward. The same logic goes for Set and Maps. + * + * Kinds are types of types. + * + * kind UnionConfig = { + * cases: Union<{ + * value: b, + * subUnions: UnionConfig[] + * }>, + * path: string[] + * } + * FindUnions :: Pattern a p => a -> p -> UnionConfig[] + */ +export type FindUnions = unknown extends p ? [] : IsAny

extends true ? [] : Length extends 5 ? [] : IsUnion extends true ? [ + { + cases: a extends any ? { + value: a; + subUnions: FindUnionsMany; + } : never; + path: path; + } +] : [a, p] extends [readonly any[], readonly any[]] ? [a, p] extends [ + readonly [infer a1, infer a2, infer a3, infer a4, infer a5], + readonly [infer p1, infer p2, infer p3, infer p4, infer p5] +] ? [ + ...FindUnions, + ...FindUnions, + ...FindUnions, + ...FindUnions, + ...FindUnions +] : [a, p] extends [ + readonly [infer a1, infer a2, infer a3, infer a4], + readonly [infer p1, infer p2, infer p3, infer p4] +] ? [ + ...FindUnions, + ...FindUnions, + ...FindUnions, + ...FindUnions +] : [a, p] extends [ + readonly [infer a1, infer a2, infer a3], + readonly [infer p1, infer p2, infer p3] +] ? [ + ...FindUnions, + ...FindUnions, + ...FindUnions +] : [a, p] extends [ + readonly [infer a1, infer a2], + readonly [infer p1, infer p2] +] ? [...FindUnions, ...FindUnions] : [a, p] extends [readonly [infer a1], readonly [infer p1]] ? FindUnions : p extends readonly [] | readonly [any, ...any] | readonly [...any, any] ? IsStrictArray> extends false ? [] : [ + ArrayToVariadicUnion extends infer aUnion ? { + cases: aUnion extends any ? { + value: aUnion; + subUnions: []; + } : never; + path: path; + } : never +] : [] : a extends Set ? [] : a extends Map ? [] : [IsPlainObject, IsPlainObject

] extends [true, true] ? Flatten; +}>> : []; +export type ArrayToVariadicUnion = MaybeAddReadonly<(input extends readonly [any, ...any] | readonly [...any, any] ? never : []) | (excluded extends readonly [...any, any] ? [...Extract, ValueOf] : [ValueOf, ...Extract]), IsReadonlyArray>; +export type Distribute = unions extends readonly [ + { + cases: infer cases; + path: infer path; + }, + ...infer tail +] ? cases extends { + value: infer value; + subUnions: infer subUnions; +} ? [ + [ + value, + path + ], + ...Distribute>, + ...Distribute +] : never : []; diff --git a/dist/types/DistributeUnions.d.ts b/dist/types/DistributeUnions.d.ts new file mode 100644 index 00000000..3410864e --- /dev/null +++ b/dist/types/DistributeUnions.d.ts @@ -0,0 +1,111 @@ +import { BuildMany } from './BuildMany.js'; +import type { IsAny, Values, Flatten, IsUnion, IsPlainObject, Length, UnionToTuple, IsReadonlyArray, ValueOf, MaybeAddReadonly, IsStrictArray } from './helpers.js'; +import { IsMatching } from './IsMatching.js'; +/** + * DistributeMatchingUnions takes two arguments: + * - a data structure of type `a` containing unions + * - a pattern `p`, matching this data structure + * and turns it into a union of all possible + * combination of each unions contained in `a` that matches `p`. + * + * It does this in 3 main steps: + * - 1. Find all unions contained in the data structure, that matches `p` + * with `FindUnions`. It returns a tree of [union, path] pairs. + * - 2. this tree is passed to the `Distribute` type level function, + * Which turns it into a union of list of `[singleValue, path]` pairs. + * Each list correspond to one of the possible combination of the unions + * found in `a`. + * - 3. build a data structure with the same shape as `a` for each combination + * and return the union of these data structures. + * + * @example + * type t1 = DistributeMatchingUnions<['a' | 'b', 1 | 2], ['a', 1]>; + * // => ['a', 1] | ['a', 2] | ['b', 1] | ['b', 2] + * + * type t2 = DistributeMatchingUnions<['a' | 'b', 1 | 2], ['a', unknown]>; + * // => ['a', 1 | 2] | ['b', 1 | 2] + */ +export type DistributeMatchingUnions = IsAny extends true ? any : BuildMany>>; +export type FindUnionsMany = UnionToTuple<(p extends any ? IsMatching extends true ? FindUnions : [] : never) extends readonly (infer T)[] ? T : never>; +/** + * The reason we don't look further down the tree with lists, + * Set and Maps is that they can be heterogeneous, + * so matching on a A[] for a in input of (A|B)[] + * doesn't rule anything out. You can still have + * a (A|B)[] afterward. The same logic goes for Set and Maps. + * + * Kinds are types of types. + * + * kind UnionConfig = { + * cases: Union<{ + * value: b, + * subUnions: UnionConfig[] + * }>, + * path: string[] + * } + * FindUnions :: Pattern a p => a -> p -> UnionConfig[] + */ +export type FindUnions = unknown extends p ? [] : IsAny

extends true ? [] : Length extends 5 ? [] : IsUnion extends true ? [ + { + cases: a extends any ? { + value: a; + subUnions: FindUnionsMany; + } : never; + path: path; + } +] : [a, p] extends [readonly any[], readonly any[]] ? [a, p] extends [ + readonly [infer a1, infer a2, infer a3, infer a4, infer a5], + readonly [infer p1, infer p2, infer p3, infer p4, infer p5] +] ? [ + ...FindUnions, + ...FindUnions, + ...FindUnions, + ...FindUnions, + ...FindUnions +] : [a, p] extends [ + readonly [infer a1, infer a2, infer a3, infer a4], + readonly [infer p1, infer p2, infer p3, infer p4] +] ? [ + ...FindUnions, + ...FindUnions, + ...FindUnions, + ...FindUnions +] : [a, p] extends [ + readonly [infer a1, infer a2, infer a3], + readonly [infer p1, infer p2, infer p3] +] ? [ + ...FindUnions, + ...FindUnions, + ...FindUnions +] : [a, p] extends [ + readonly [infer a1, infer a2], + readonly [infer p1, infer p2] +] ? [...FindUnions, ...FindUnions] : [a, p] extends [readonly [infer a1], readonly [infer p1]] ? FindUnions : p extends readonly [] | readonly [any, ...any] | readonly [...any, any] ? IsStrictArray> extends false ? [] : [ + ArrayToVariadicUnion extends infer aUnion ? { + cases: aUnion extends any ? { + value: aUnion; + subUnions: []; + } : never; + path: path; + } : never +] : [] : a extends Set ? [] : a extends Map ? [] : [IsPlainObject, IsPlainObject

] extends [true, true] ? Flatten; +}>> : []; +export type ArrayToVariadicUnion = MaybeAddReadonly<(input extends readonly [any, ...any] | readonly [...any, any] ? never : []) | (excluded extends readonly [...any, any] ? [...Extract, ValueOf] : [ValueOf, ...Extract]), IsReadonlyArray>; +export type Distribute = unions extends readonly [ + { + cases: infer cases; + path: infer path; + }, + ...infer tail +] ? cases extends { + value: infer value; + subUnions: infer subUnions; +} ? [ + [ + value, + path + ], + ...Distribute>, + ...Distribute +] : never : []; diff --git a/dist/types/ExtractPreciseValue.d.cts b/dist/types/ExtractPreciseValue.d.cts new file mode 100644 index 00000000..ae77c322 --- /dev/null +++ b/dist/types/ExtractPreciseValue.d.cts @@ -0,0 +1,27 @@ +import type { Override } from './Pattern.cjs'; +import type { BuiltInObjects, Compute, Contains, IsPlainObject, IsReadonlyArray, LeastUpperBound, MaybeAddReadonly, ValueOf } from './helpers.cjs'; +export type ExtractPreciseValue = b extends Override ? b1 : unknown extends b ? a : 0 extends 1 & b ? a : 0 extends 1 & a ? b : b extends readonly any[] ? ExtractPreciseArrayValue> : b extends Map ? a extends Map ? Map, ExtractPreciseValue> : LeastUpperBound : b extends Set ? a extends Set ? Set> : LeastUpperBound : IsPlainObject extends true ? a extends object ? a extends b ? a : b extends a ? Contains extends true ? never : Contains, {}> extends true ? never : [ + Exclude +] extends [never] ? b : Compute> : [keyof a & keyof b] extends [never] ? never : Compute<{ + [k in keyof a as k extends keyof b ? never : k]: a[k]; +} & { + [k in keyof b]: k extends keyof a ? ExtractPreciseValue : b[k]; +}> extends infer result ? Contains, never> extends true ? never : result : never : LeastUpperBound : LeastUpperBound; +type ExtractPreciseArrayValue = a extends readonly (infer aItem)[] ? b extends readonly [] ? MaybeAddReadonly<[...startOutput, ...endOutput], isReadonly> : b extends readonly [infer b1, ...infer bRest] ? a extends readonly [infer a1, ...infer aRest] ? ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : b extends readonly [...infer bInit, infer b1] ? a extends readonly [...infer aInit, infer a1] ? ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : ExtractPreciseValue> extends infer currentValue ? [currentValue] extends [never] ? never : MaybeAddReadonly<[ + ...startOutput, + ...currentValue[], + ...endOutput +], isReadonly> : never : LeastUpperBound; +export {}; diff --git a/dist/types/ExtractPreciseValue.d.ts b/dist/types/ExtractPreciseValue.d.ts new file mode 100644 index 00000000..edf2b08d --- /dev/null +++ b/dist/types/ExtractPreciseValue.d.ts @@ -0,0 +1,27 @@ +import type { Override } from './Pattern.js'; +import type { BuiltInObjects, Compute, Contains, IsPlainObject, IsReadonlyArray, LeastUpperBound, MaybeAddReadonly, ValueOf } from './helpers.js'; +export type ExtractPreciseValue = b extends Override ? b1 : unknown extends b ? a : 0 extends 1 & b ? a : 0 extends 1 & a ? b : b extends readonly any[] ? ExtractPreciseArrayValue> : b extends Map ? a extends Map ? Map, ExtractPreciseValue> : LeastUpperBound : b extends Set ? a extends Set ? Set> : LeastUpperBound : IsPlainObject extends true ? a extends object ? a extends b ? a : b extends a ? Contains extends true ? never : Contains, {}> extends true ? never : [ + Exclude +] extends [never] ? b : Compute> : [keyof a & keyof b] extends [never] ? never : Compute<{ + [k in keyof a as k extends keyof b ? never : k]: a[k]; +} & { + [k in keyof b]: k extends keyof a ? ExtractPreciseValue : b[k]; +}> extends infer result ? Contains, never> extends true ? never : result : never : LeastUpperBound : LeastUpperBound; +type ExtractPreciseArrayValue = a extends readonly (infer aItem)[] ? b extends readonly [] ? MaybeAddReadonly<[...startOutput, ...endOutput], isReadonly> : b extends readonly [infer b1, ...infer bRest] ? a extends readonly [infer a1, ...infer aRest] ? ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : b extends readonly [...infer bInit, infer b1] ? a extends readonly [...infer aInit, infer a1] ? ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : ExtractPreciseValue extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue : never : ExtractPreciseValue> extends infer currentValue ? [currentValue] extends [never] ? never : MaybeAddReadonly<[ + ...startOutput, + ...currentValue[], + ...endOutput +], isReadonly> : never : LeastUpperBound; +export {}; diff --git a/dist/types/FindSelected.d.cts b/dist/types/FindSelected.d.cts new file mode 100644 index 00000000..d6c3234a --- /dev/null +++ b/dist/types/FindSelected.d.cts @@ -0,0 +1,65 @@ +import type * as symbols from '../internals/symbols.cjs'; +import type { AnyMatcher, Matcher, Pattern } from './Pattern.cjs'; +import type { Equal, Primitives, ValueOf, MergeUnion, IsUnion } from './helpers.cjs'; +type SelectionsRecord = Record; +export type None = { + type: 'none'; +}; +export type Some = { + type: 'some'; + key: key; +}; +export type SelectionType = None | Some; +type MapOptional = { + [k in keyof selections]: selections[k] extends [infer v, infer subpath] ? [v | undefined, subpath] : never; +}; +type MapList = { + [k in keyof selections]: selections[k] extends [infer v, infer subpath] ? [v[], subpath] : never; +}; +type ReduceFindSelectionUnion = ps extends readonly [infer head, ...infer tail] ? ReduceFindSelectionUnion> : output; +type FindSelectionUnionInArray = i extends readonly (infer iItem)[] ? p extends readonly [] ? output : p extends readonly [infer p1, ...infer pRest] ? i extends readonly [infer i1, ...infer iRest] ? FindSelectionUnionInArray> : FindSelectionUnionInArray> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? FindSelectionUnionInArray> : FindSelectionUnionInArray> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? output | FindSelectionUnion : output | FindSelectionUnion, [ + ...path, + Extract['length'] +]> : output; +export type FindSelectionUnion = 0 extends 1 & i ? never : 0 extends 1 & p ? never : p extends Primitives ? never : p extends Matcher ? { + select: sel extends Some ? { + [kk in k]: [i, path]; + } | FindSelectionUnion : never; + array: i extends readonly (infer iItem)[] ? MapList> : never; + map: never; + set: never; + optional: MapOptional>; + or: MapOptional>>; + and: ReduceFindSelectionUnion>; + not: never; + default: sel extends Some ? { + [kk in k]: [i, path]; + } : never; + custom: never; +}[matcherType] : p extends readonly any[] ? FindSelectionUnionInArray : p extends {} ? i extends {} ? { + [k in keyof p]: k extends keyof i ? FindSelectionUnion : never; +}[keyof p] : never : never; +export type SeveralAnonymousSelectError)` instead'> = { + __error: never; +} & a; +export type MixedNamedAndAnonymousSelectError = { + __error: never; +} & a; +export type SelectionToArgs = symbols.anonymousSelectKey extends keyof selections ? IsUnion extends true ? SeveralAnonymousSelectError : keyof selections extends symbols.anonymousSelectKey ? selections[symbols.anonymousSelectKey][0] : MixedNamedAndAnonymousSelectError : { + [k in keyof selections]: selections[k][0]; +}; +export type Selections = FindSelectionUnion extends infer u ? [u] extends [never] ? i : SelectionToArgs, SelectionsRecord>> : i; +export type FindSelected = Equal> extends true ? i : Selections; +export {}; diff --git a/dist/types/FindSelected.d.ts b/dist/types/FindSelected.d.ts new file mode 100644 index 00000000..42b11446 --- /dev/null +++ b/dist/types/FindSelected.d.ts @@ -0,0 +1,65 @@ +import type * as symbols from '../internals/symbols.js'; +import type { AnyMatcher, Matcher, Pattern } from './Pattern.js'; +import type { Equal, Primitives, ValueOf, MergeUnion, IsUnion } from './helpers.js'; +type SelectionsRecord = Record; +export type None = { + type: 'none'; +}; +export type Some = { + type: 'some'; + key: key; +}; +export type SelectionType = None | Some; +type MapOptional = { + [k in keyof selections]: selections[k] extends [infer v, infer subpath] ? [v | undefined, subpath] : never; +}; +type MapList = { + [k in keyof selections]: selections[k] extends [infer v, infer subpath] ? [v[], subpath] : never; +}; +type ReduceFindSelectionUnion = ps extends readonly [infer head, ...infer tail] ? ReduceFindSelectionUnion> : output; +type FindSelectionUnionInArray = i extends readonly (infer iItem)[] ? p extends readonly [] ? output : p extends readonly [infer p1, ...infer pRest] ? i extends readonly [infer i1, ...infer iRest] ? FindSelectionUnionInArray> : FindSelectionUnionInArray> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? FindSelectionUnionInArray> : FindSelectionUnionInArray> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? output | FindSelectionUnion : output | FindSelectionUnion, [ + ...path, + Extract['length'] +]> : output; +export type FindSelectionUnion = 0 extends 1 & i ? never : 0 extends 1 & p ? never : p extends Primitives ? never : p extends Matcher ? { + select: sel extends Some ? { + [kk in k]: [i, path]; + } | FindSelectionUnion : never; + array: i extends readonly (infer iItem)[] ? MapList> : never; + map: never; + set: never; + optional: MapOptional>; + or: MapOptional>>; + and: ReduceFindSelectionUnion>; + not: never; + default: sel extends Some ? { + [kk in k]: [i, path]; + } : never; + custom: never; +}[matcherType] : p extends readonly any[] ? FindSelectionUnionInArray : p extends {} ? i extends {} ? { + [k in keyof p]: k extends keyof i ? FindSelectionUnion : never; +}[keyof p] : never : never; +export type SeveralAnonymousSelectError)` instead'> = { + __error: never; +} & a; +export type MixedNamedAndAnonymousSelectError = { + __error: never; +} & a; +export type SelectionToArgs = symbols.anonymousSelectKey extends keyof selections ? IsUnion extends true ? SeveralAnonymousSelectError : keyof selections extends symbols.anonymousSelectKey ? selections[symbols.anonymousSelectKey][0] : MixedNamedAndAnonymousSelectError : { + [k in keyof selections]: selections[k][0]; +}; +export type Selections = FindSelectionUnion extends infer u ? [u] extends [never] ? i : SelectionToArgs, SelectionsRecord>> : i; +export type FindSelected = Equal> extends true ? i : Selections; +export {}; diff --git a/dist/types/InvertPattern.d.cts b/dist/types/InvertPattern.d.cts new file mode 100644 index 00000000..bc2eea87 --- /dev/null +++ b/dist/types/InvertPattern.d.cts @@ -0,0 +1,102 @@ +import { DeepExclude } from './DeepExclude.cjs'; +import { IsPlainObject, Primitives, IsLiteral, ValueOf, Compute, Equal, Extends, Not, All, NonLiteralPrimitive, MaybeAddReadonly, IsReadonlyArray, MapKey, MapValue, SetValue, ExtractPlainObject, GetKey, Call, Fn, ReadonlyArrayValue, WithDefault } from './helpers.cjs'; +import type { Matcher, Pattern, Override, AnyMatcher } from './Pattern.cjs'; +type OptionalKeys

= ValueOf<{ + [k in keyof p]: 0 extends 1 & p[k] ? never : p[k] extends Matcher ? matcherType extends 'optional' ? k : never : never; +}>; +type ReduceUnion = tuple extends readonly [infer p, ...infer tail] ? ReduceUnion> : output; +type ReduceIntersection = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersection> : output; +type InvertArrayPattern = i extends readonly (infer ii)[] ? p extends readonly [] ? [...startOutput, ...endOutput] : p extends readonly [infer p1, ...infer pRest] ? i extends readonly [infer i1, ...infer iRest] ? InvertArrayPattern +], endOutput> : InvertArrayPattern +], endOutput> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? InvertArrayPattern +]> : InvertArrayPattern +]> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? [ + ...startOutput, + ...Extract, readonly any[]>, + ...endOutput +] : [...startOutput, ...InvertPatternInternal, ii>[], ...endOutput] : never; +/** + * ### InvertPatternInternal + * Since patterns have special wildcard values, we need a way + * to transform a pattern into the type of value it represents + */ +export type InvertPattern = Equal, p> extends true ? never : InvertPatternInternal; +type InvertPatternInternal = 0 extends 1 & p ? never : p extends Matcher ? { + not: DeepExclude>; + select: InvertPatternInternal; + array: InvertPatternInternal>[]; + map: subpattern extends [infer pk, infer pv] ? Map>>>, InvertPatternInternal>>>> : never; + set: Set>>>>; + optional: InvertPatternInternal> | undefined; + and: ReduceIntersection, input>; + or: ReduceUnion, input>; + default: [subpattern] extends [never] ? input : subpattern; + custom: Override : narrowedOrFn>; +}[matcherType] : p extends Primitives ? p : p extends readonly any[] ? InvertArrayPattern, unknown[]>> : IsPlainObject

extends true ? OptionalKeys

extends infer optKeys ? [optKeys] extends [never] ? { + [k in Exclude]: InvertPatternInternal, k>, unknown>>; +} : Compute<{ + [k in Exclude]: InvertPatternInternal, k>, unknown>>; +} & { + [k in Extract]?: InvertPatternInternal, k>, unknown>>; +}> : never : p; +export type ReduceIntersectionForExclude = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersectionForExclude> : output; +export type ReduceUnionForExclude = tuple extends readonly [infer p, ...infer tail] ? ReduceUnionForExclude> : output; +type ExcludeIfExists = [ + b +] extends [never] ? never : unknown extends a ? never : All<[ + Extends, + Not>, + IsLiteral +]> extends true ? never : DeepExclude; +type InvertArrayPatternForExclude = i extends readonly (infer ii)[] ? p extends readonly [] ? MaybeAddReadonly<[...startOutput, ...endOutput], isReadonly> : p extends readonly [infer p1, ...infer pRest] ? i extends readonly [infer i1, ...infer iRest] ? InvertArrayPatternForExclude +], endOutput> : InvertArrayPatternForExclude +], endOutput> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? InvertArrayPatternForExclude +]> : InvertArrayPatternForExclude +]> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? MaybeAddReadonly<[ + ...startOutput, + ...Extract, readonly any[]>, + ...endOutput +], isReadonly> : MaybeAddReadonly<[ + ...startOutput, + ...InvertPatternForExcludeInternal, ii, empty>[], + ...endOutput +], isReadonly> : empty; +/** + * ### InvertPatternForExclude + */ +export type InvertPatternForExclude = Equal, p> extends true ? never : InvertPatternForExcludeInternal; +type InvertPatternForExcludeInternal = unknown extends p ? i : [p] extends [Primitives] ? IsLiteral

extends true ? p : IsLiteral extends true ? p : empty : p extends Matcher ? { + select: InvertPatternForExcludeInternal; + array: i extends readonly (infer ii)[] ? MaybeAddReadonly[], IsReadonlyArray> : empty; + map: subpattern extends [infer pk, infer pv] ? i extends Map ? Map, InvertPatternForExcludeInternal> : empty : empty; + set: i extends Set ? Set> : empty; + optional: InvertPatternForExcludeInternal | undefined; + and: ReduceIntersectionForExclude, i>; + or: ReduceUnionForExclude, i>; + not: ExcludeIfExists>; + default: excluded; + custom: excluded extends infer narrowedOrFn extends Fn ? Call : excluded; +}[matcherType] : p extends readonly any[] ? Extract extends infer arrayInput ? InvertArrayPatternForExclude> : never : IsPlainObject

extends true ? i extends object ? [keyof p & keyof i] extends [never] ? empty : OptionalKeys

extends infer optKeys ? [optKeys] extends [never] ? { + readonly [k in keyof p]: k extends keyof i ? InvertPatternForExcludeInternal : InvertPatternInternal; +} : Compute<{ + readonly [k in Exclude]: k extends keyof i ? InvertPatternForExcludeInternal : InvertPatternInternal; +} & { + readonly [k in Extract]?: k extends keyof i ? InvertPatternForExcludeInternal : InvertPatternInternal; +}> : empty : empty : empty; +export {}; diff --git a/dist/types/InvertPattern.d.ts b/dist/types/InvertPattern.d.ts new file mode 100644 index 00000000..f11a6422 --- /dev/null +++ b/dist/types/InvertPattern.d.ts @@ -0,0 +1,102 @@ +import { DeepExclude } from './DeepExclude.js'; +import { IsPlainObject, Primitives, IsLiteral, ValueOf, Compute, Equal, Extends, Not, All, NonLiteralPrimitive, MaybeAddReadonly, IsReadonlyArray, MapKey, MapValue, SetValue, ExtractPlainObject, GetKey, Call, Fn, ReadonlyArrayValue, WithDefault } from './helpers.js'; +import type { Matcher, Pattern, Override, AnyMatcher } from './Pattern.js'; +type OptionalKeys

= ValueOf<{ + [k in keyof p]: 0 extends 1 & p[k] ? never : p[k] extends Matcher ? matcherType extends 'optional' ? k : never : never; +}>; +type ReduceUnion = tuple extends readonly [infer p, ...infer tail] ? ReduceUnion> : output; +type ReduceIntersection = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersection> : output; +type InvertArrayPattern = i extends readonly (infer ii)[] ? p extends readonly [] ? [...startOutput, ...endOutput] : p extends readonly [infer p1, ...infer pRest] ? i extends readonly [infer i1, ...infer iRest] ? InvertArrayPattern +], endOutput> : InvertArrayPattern +], endOutput> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? InvertArrayPattern +]> : InvertArrayPattern +]> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? [ + ...startOutput, + ...Extract, readonly any[]>, + ...endOutput +] : [...startOutput, ...InvertPatternInternal, ii>[], ...endOutput] : never; +/** + * ### InvertPatternInternal + * Since patterns have special wildcard values, we need a way + * to transform a pattern into the type of value it represents + */ +export type InvertPattern = Equal, p> extends true ? never : InvertPatternInternal; +type InvertPatternInternal = 0 extends 1 & p ? never : p extends Matcher ? { + not: DeepExclude>; + select: InvertPatternInternal; + array: InvertPatternInternal>[]; + map: subpattern extends [infer pk, infer pv] ? Map>>>, InvertPatternInternal>>>> : never; + set: Set>>>>; + optional: InvertPatternInternal> | undefined; + and: ReduceIntersection, input>; + or: ReduceUnion, input>; + default: [subpattern] extends [never] ? input : subpattern; + custom: Override : narrowedOrFn>; +}[matcherType] : p extends Primitives ? p : p extends readonly any[] ? InvertArrayPattern, unknown[]>> : IsPlainObject

extends true ? OptionalKeys

extends infer optKeys ? [optKeys] extends [never] ? { + [k in Exclude]: InvertPatternInternal, k>, unknown>>; +} : Compute<{ + [k in Exclude]: InvertPatternInternal, k>, unknown>>; +} & { + [k in Extract]?: InvertPatternInternal, k>, unknown>>; +}> : never : p; +export type ReduceIntersectionForExclude = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersectionForExclude> : output; +export type ReduceUnionForExclude = tuple extends readonly [infer p, ...infer tail] ? ReduceUnionForExclude> : output; +type ExcludeIfExists = [ + b +] extends [never] ? never : unknown extends a ? never : All<[ + Extends, + Not>, + IsLiteral +]> extends true ? never : DeepExclude; +type InvertArrayPatternForExclude = i extends readonly (infer ii)[] ? p extends readonly [] ? MaybeAddReadonly<[...startOutput, ...endOutput], isReadonly> : p extends readonly [infer p1, ...infer pRest] ? i extends readonly [infer i1, ...infer iRest] ? InvertArrayPatternForExclude +], endOutput> : InvertArrayPatternForExclude +], endOutput> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? InvertArrayPatternForExclude +]> : InvertArrayPatternForExclude +]> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? MaybeAddReadonly<[ + ...startOutput, + ...Extract, readonly any[]>, + ...endOutput +], isReadonly> : MaybeAddReadonly<[ + ...startOutput, + ...InvertPatternForExcludeInternal, ii, empty>[], + ...endOutput +], isReadonly> : empty; +/** + * ### InvertPatternForExclude + */ +export type InvertPatternForExclude = Equal, p> extends true ? never : InvertPatternForExcludeInternal; +type InvertPatternForExcludeInternal = unknown extends p ? i : [p] extends [Primitives] ? IsLiteral

extends true ? p : IsLiteral extends true ? p : empty : p extends Matcher ? { + select: InvertPatternForExcludeInternal; + array: i extends readonly (infer ii)[] ? MaybeAddReadonly[], IsReadonlyArray> : empty; + map: subpattern extends [infer pk, infer pv] ? i extends Map ? Map, InvertPatternForExcludeInternal> : empty : empty; + set: i extends Set ? Set> : empty; + optional: InvertPatternForExcludeInternal | undefined; + and: ReduceIntersectionForExclude, i>; + or: ReduceUnionForExclude, i>; + not: ExcludeIfExists>; + default: excluded; + custom: excluded extends infer narrowedOrFn extends Fn ? Call : excluded; +}[matcherType] : p extends readonly any[] ? Extract extends infer arrayInput ? InvertArrayPatternForExclude> : never : IsPlainObject

extends true ? i extends object ? [keyof p & keyof i] extends [never] ? empty : OptionalKeys

extends infer optKeys ? [optKeys] extends [never] ? { + readonly [k in keyof p]: k extends keyof i ? InvertPatternForExcludeInternal : InvertPatternInternal; +} : Compute<{ + readonly [k in Exclude]: k extends keyof i ? InvertPatternForExcludeInternal : InvertPatternInternal; +} & { + readonly [k in Extract]?: k extends keyof i ? InvertPatternForExcludeInternal : InvertPatternInternal; +}> : empty : empty : empty; +export {}; diff --git a/dist/types/IsMatching.d.cts b/dist/types/IsMatching.d.cts new file mode 100644 index 00000000..da864da5 --- /dev/null +++ b/dist/types/IsMatching.d.cts @@ -0,0 +1,13 @@ +import { Primitives, IsPlainObject, IsUnion, ValueOf, Length, IsLiteral, All, Equal } from './helpers.cjs'; +type IsMatchingTuple = [ + a, + b +] extends [readonly [], readonly []] ? true : [a, b] extends [ + readonly [infer a1, ...infer aRest], + readonly [infer b1, ...infer bRest] +] ? IsMatching extends true ? IsMatchingTuple : false : false; +type IsMatchingArray = b extends readonly [] ? true : b extends readonly [infer b1, ...infer bRest] ? a extends readonly [infer a1, ...infer aRest] ? IsMatching extends true ? IsMatchingArray : false : a extends readonly [] ? false : IsMatching, b1> extends true ? IsMatchingArray : false : b extends readonly [...infer bInit, infer b1] ? a extends readonly [...infer aInit, infer a1] ? IsMatching extends true ? IsMatchingArray : false : a extends readonly [] ? false : IsMatching, b1> extends true ? IsMatchingArray : false : IsMatching, ValueOf>; +export type IsMatching = true extends IsUnion | IsUnion ? true extends (b extends any ? (a extends any ? IsMatching : never) : never) ? true : false : unknown extends b ? true : {} extends b ? true : b extends Primitives ? a extends b ? true : b extends a ? true : false : Equal extends true ? true : b extends readonly any[] ? a extends readonly any[] ? All<[IsLiteral>, IsLiteral>]> extends true ? Equal, Length> extends false ? false : IsMatchingTuple : IsMatchingArray : false : IsPlainObject extends true ? true extends (a extends any ? [keyof b & keyof a] extends [never] ? false : { + [k in keyof b & keyof a]: IsMatching; +}[keyof b & keyof a] extends true ? true : false : never) ? true : false : b extends a ? true : false; +export {}; diff --git a/dist/types/IsMatching.d.ts b/dist/types/IsMatching.d.ts new file mode 100644 index 00000000..cdb74c30 --- /dev/null +++ b/dist/types/IsMatching.d.ts @@ -0,0 +1,13 @@ +import { Primitives, IsPlainObject, IsUnion, ValueOf, Length, IsLiteral, All, Equal } from './helpers.js'; +type IsMatchingTuple = [ + a, + b +] extends [readonly [], readonly []] ? true : [a, b] extends [ + readonly [infer a1, ...infer aRest], + readonly [infer b1, ...infer bRest] +] ? IsMatching extends true ? IsMatchingTuple : false : false; +type IsMatchingArray = b extends readonly [] ? true : b extends readonly [infer b1, ...infer bRest] ? a extends readonly [infer a1, ...infer aRest] ? IsMatching extends true ? IsMatchingArray : false : a extends readonly [] ? false : IsMatching, b1> extends true ? IsMatchingArray : false : b extends readonly [...infer bInit, infer b1] ? a extends readonly [...infer aInit, infer a1] ? IsMatching extends true ? IsMatchingArray : false : a extends readonly [] ? false : IsMatching, b1> extends true ? IsMatchingArray : false : IsMatching, ValueOf>; +export type IsMatching = true extends IsUnion | IsUnion ? true extends (b extends any ? (a extends any ? IsMatching : never) : never) ? true : false : unknown extends b ? true : {} extends b ? true : b extends Primitives ? a extends b ? true : b extends a ? true : false : Equal extends true ? true : b extends readonly any[] ? a extends readonly any[] ? All<[IsLiteral>, IsLiteral>]> extends true ? Equal, Length> extends false ? false : IsMatchingTuple : IsMatchingArray : false : IsPlainObject extends true ? true extends (a extends any ? [keyof b & keyof a] extends [never] ? false : { + [k in keyof b & keyof a]: IsMatching; +}[keyof b & keyof a] extends true ? true : false : never) ? true : false : b extends a ? true : false; +export {}; diff --git a/dist/types/Match.d.cts b/dist/types/Match.d.cts new file mode 100644 index 00000000..c3761530 --- /dev/null +++ b/dist/types/Match.d.cts @@ -0,0 +1,129 @@ +import type * as symbols from '../internals/symbols.cjs'; +import type { Pattern, MatchedValue } from './Pattern.cjs'; +import type { InvertPatternForExclude, InvertPattern } from './InvertPattern.cjs'; +import type { DeepExclude } from './DeepExclude.cjs'; +import type { Union, GuardValue, IsNever } from './helpers.cjs'; +import type { FindSelected } from './FindSelected.cjs'; +export type PickReturnValue = a extends symbols.unset ? b : a; +interface NonExhaustiveError { + __nonExhaustive: never; +} +interface TSPatternError { + __nonExhaustive: never; +} +/** + * #### Match + * An interface to create a pattern matching clause. + */ +export type Match = { + /** + * `.with(pattern, handler)` Registers a pattern and an handler function that + * will be called if the pattern matches the input value. + * + * [Read the documentation for `.with()` on GitHub](https://github.com/gvergnaud/ts-pattern#with) + **/ + with, c, value extends MatchedValue>>(pattern: IsNever

extends true ? Pattern : p, handler: (selections: FindSelected, value: value) => PickReturnValue): InvertPatternForExclude extends infer excluded ? Match, o, [ + ...handledCases, + excluded + ], Union> : never; + with, const p2 extends Pattern, c, p extends p1 | p2, value extends p extends any ? MatchedValue> : never>(p1: p1, p2: p2, handler: (value: value) => PickReturnValue): [ + InvertPatternForExclude, + InvertPatternForExclude + ] extends [infer excluded1, infer excluded2] ? Match, o, [ + ...handledCases, + excluded1, + excluded2 + ], Union> : never; + with, const p2 extends Pattern, const p3 extends Pattern, const ps extends readonly Pattern[], c, p extends p1 | p2 | p3 | ps[number], value extends MatchedValue>>(...args: [ + p1: p1, + p2: p2, + p3: p3, + ...patterns: ps, + handler: (value: value) => PickReturnValue + ]): [ + InvertPatternForExclude, + InvertPatternForExclude, + InvertPatternForExclude, + MakeTuples + ] extends [ + infer excluded1, + infer excluded2, + infer excluded3, + infer excludedRest + ] ? Match[number]>, o, [ + ...handledCases, + excluded1, + excluded2, + excluded3, + ...Extract + ], Union> : never; + with, pred extends (value: MatchedValue>) => unknown, c, value extends GuardValue>(pattern: pat, predicate: pred, handler: (selections: FindSelected, value: value) => PickReturnValue): pred extends (value: any) => value is infer narrowed ? Match, o, [ + ...handledCases, + narrowed + ], Union> : Match>; + /** + * `.when(predicate, handler)` Registers a predicate function and an handler function. + * If the predicate returns true, the handler function will be called. + * + * [Read the documentation for `.when()` on GitHub](https://github.com/gvergnaud/ts-pattern#when) + **/ + when unknown, c, value extends GuardValue>(predicate: pred, handler: (value: value) => PickReturnValue): pred extends (value: any) => value is infer narrowed ? Match, o, [ + ...handledCases, + narrowed + ], Union> : Match>; + /** + * `.otherwise()` takes a **default handler function** that will be + * called if no previous pattern matched your input. + * + * Equivalent to `.with(P._, () => x).exhaustive()` + * + * [Read the documentation for `.otherwise()` on GitHub](https://github.com/gvergnaud/ts-pattern#otherwise) + * + **/ + otherwise(handler: (value: i) => PickReturnValue): PickReturnValue>; + /** + * `.exhaustive()` checks that all cases are handled, and returns the result value. + * + * If you get a `NonExhaustiveError`, it means that you aren't handling + * all cases. You should probably add another `.with(...)` clause + * to match the missing case and prevent runtime errors. + * + * [Read the documentation for `.exhaustive()` on GitHub](https://github.com/gvergnaud/ts-pattern#exhaustive) + * + * */ + exhaustive: DeepExcludeAll extends infer remainingCases ? [remainingCases] extends [never] ? () => PickReturnValue : NonExhaustiveError : never; + /** + * `.run()` return the resulting value. + * + * ⚠️ calling this function is unsafe, and may throw if no pattern matches your input. + * */ + run(): PickReturnValue; + /** + * `.returnType()` Lets you specify the return type for all of your branches. + * + * [Read the documentation for `.returnType()` on GitHub](https://github.com/gvergnaud/ts-pattern#returnType) + * */ + returnType: [inferredOutput] extends [never] ? () => Match : TSPatternError<'calling `.returnType()` is only allowed directly after `match(...)`.'>; +}; +/** + * Potential for optimization here: + * + * Since DeepExclude distributes the union of the input type, it can + * generate very large union types on patterns touching several unions at once. + * If we were sorting patterns from those which distribute the smallest + * amount of union types to those which distribute the largest, we would eliminate + * cheap cases more quickly and have less cases in the input type for patterns + * that will be expensive to exclude. + * + * This pre supposes that we have a cheap way of telling if the number + * of union types a pattern touches and a cheap way of sorting the tuple + * of patterns. + * - For the first part, we could reuse `FindMatchingUnions` and pick the `length` + * of the returned tuple. + * - For the second part though I'm not aware a cheap way of sorting a tuple. + */ +type DeepExcludeAll = [a] extends [never] ? never : tupleList extends [infer excluded, ...infer tail] ? DeepExcludeAll, tail> : a; +type MakeTuples = { + -readonly [index in keyof ps]: InvertPatternForExclude; +}; +export {}; diff --git a/dist/types/Match.d.ts b/dist/types/Match.d.ts new file mode 100644 index 00000000..adf0248a --- /dev/null +++ b/dist/types/Match.d.ts @@ -0,0 +1,129 @@ +import type * as symbols from '../internals/symbols.js'; +import type { Pattern, MatchedValue } from './Pattern.js'; +import type { InvertPatternForExclude, InvertPattern } from './InvertPattern.js'; +import type { DeepExclude } from './DeepExclude.js'; +import type { Union, GuardValue, IsNever } from './helpers.js'; +import type { FindSelected } from './FindSelected.js'; +export type PickReturnValue = a extends symbols.unset ? b : a; +interface NonExhaustiveError { + __nonExhaustive: never; +} +interface TSPatternError { + __nonExhaustive: never; +} +/** + * #### Match + * An interface to create a pattern matching clause. + */ +export type Match = { + /** + * `.with(pattern, handler)` Registers a pattern and an handler function that + * will be called if the pattern matches the input value. + * + * [Read the documentation for `.with()` on GitHub](https://github.com/gvergnaud/ts-pattern#with) + **/ + with, c, value extends MatchedValue>>(pattern: IsNever

extends true ? Pattern : p, handler: (selections: FindSelected, value: value) => PickReturnValue): InvertPatternForExclude extends infer excluded ? Match, o, [ + ...handledCases, + excluded + ], Union> : never; + with, const p2 extends Pattern, c, p extends p1 | p2, value extends p extends any ? MatchedValue> : never>(p1: p1, p2: p2, handler: (value: value) => PickReturnValue): [ + InvertPatternForExclude, + InvertPatternForExclude + ] extends [infer excluded1, infer excluded2] ? Match, o, [ + ...handledCases, + excluded1, + excluded2 + ], Union> : never; + with, const p2 extends Pattern, const p3 extends Pattern, const ps extends readonly Pattern[], c, p extends p1 | p2 | p3 | ps[number], value extends MatchedValue>>(...args: [ + p1: p1, + p2: p2, + p3: p3, + ...patterns: ps, + handler: (value: value) => PickReturnValue + ]): [ + InvertPatternForExclude, + InvertPatternForExclude, + InvertPatternForExclude, + MakeTuples + ] extends [ + infer excluded1, + infer excluded2, + infer excluded3, + infer excludedRest + ] ? Match[number]>, o, [ + ...handledCases, + excluded1, + excluded2, + excluded3, + ...Extract + ], Union> : never; + with, pred extends (value: MatchedValue>) => unknown, c, value extends GuardValue>(pattern: pat, predicate: pred, handler: (selections: FindSelected, value: value) => PickReturnValue): pred extends (value: any) => value is infer narrowed ? Match, o, [ + ...handledCases, + narrowed + ], Union> : Match>; + /** + * `.when(predicate, handler)` Registers a predicate function and an handler function. + * If the predicate returns true, the handler function will be called. + * + * [Read the documentation for `.when()` on GitHub](https://github.com/gvergnaud/ts-pattern#when) + **/ + when unknown, c, value extends GuardValue>(predicate: pred, handler: (value: value) => PickReturnValue): pred extends (value: any) => value is infer narrowed ? Match, o, [ + ...handledCases, + narrowed + ], Union> : Match>; + /** + * `.otherwise()` takes a **default handler function** that will be + * called if no previous pattern matched your input. + * + * Equivalent to `.with(P._, () => x).exhaustive()` + * + * [Read the documentation for `.otherwise()` on GitHub](https://github.com/gvergnaud/ts-pattern#otherwise) + * + **/ + otherwise(handler: (value: i) => PickReturnValue): PickReturnValue>; + /** + * `.exhaustive()` checks that all cases are handled, and returns the result value. + * + * If you get a `NonExhaustiveError`, it means that you aren't handling + * all cases. You should probably add another `.with(...)` clause + * to match the missing case and prevent runtime errors. + * + * [Read the documentation for `.exhaustive()` on GitHub](https://github.com/gvergnaud/ts-pattern#exhaustive) + * + * */ + exhaustive: DeepExcludeAll extends infer remainingCases ? [remainingCases] extends [never] ? () => PickReturnValue : NonExhaustiveError : never; + /** + * `.run()` return the resulting value. + * + * ⚠️ calling this function is unsafe, and may throw if no pattern matches your input. + * */ + run(): PickReturnValue; + /** + * `.returnType()` Lets you specify the return type for all of your branches. + * + * [Read the documentation for `.returnType()` on GitHub](https://github.com/gvergnaud/ts-pattern#returnType) + * */ + returnType: [inferredOutput] extends [never] ? () => Match : TSPatternError<'calling `.returnType()` is only allowed directly after `match(...)`.'>; +}; +/** + * Potential for optimization here: + * + * Since DeepExclude distributes the union of the input type, it can + * generate very large union types on patterns touching several unions at once. + * If we were sorting patterns from those which distribute the smallest + * amount of union types to those which distribute the largest, we would eliminate + * cheap cases more quickly and have less cases in the input type for patterns + * that will be expensive to exclude. + * + * This pre supposes that we have a cheap way of telling if the number + * of union types a pattern touches and a cheap way of sorting the tuple + * of patterns. + * - For the first part, we could reuse `FindMatchingUnions` and pick the `length` + * of the returned tuple. + * - For the second part though I'm not aware a cheap way of sorting a tuple. + */ +type DeepExcludeAll = [a] extends [never] ? never : tupleList extends [infer excluded, ...infer tail] ? DeepExcludeAll, tail> : a; +type MakeTuples = { + -readonly [index in keyof ps]: InvertPatternForExclude; +}; +export {}; diff --git a/dist/types/Pattern.d.cts b/dist/types/Pattern.d.cts new file mode 100644 index 00000000..ff4ee31f --- /dev/null +++ b/dist/types/Pattern.d.cts @@ -0,0 +1,396 @@ +import type * as symbols from '../internals/symbols.cjs'; +import { MergeUnion, Primitives, WithDefault } from './helpers.cjs'; +import { None, Some, SelectionType } from './FindSelected.cjs'; +import { matcher } from '../patterns.cjs'; +import { ExtractPreciseValue } from './ExtractPreciseValue.cjs'; +export type MatcherType = 'not' | 'optional' | 'or' | 'and' | 'array' | 'map' | 'set' | 'select' | 'default' | 'custom'; +export type MatcherProtocol = { + match: (value: I | input) => MatchResult; + getSelectionKeys?: () => string[]; + matcherType?: matcherType; +}; +export type MatchResult = { + matched: boolean; + selections?: Record; +}; +/** + * A `Matcher` is an object implementing the match + * protocol. It must define a `symbols.matcher` property + * which returns an object with a `match()` method, taking + * the input value and returning whether the pattern matches + * or not, along with optional selections. + */ +export interface Matcher { + [matcher](): MatcherProtocol; + [symbols.isVariadic]?: boolean; +} +type PatternMatcher = Matcher; +export type MatchedValue = WithDefault, a>; +export type AnyMatcher = Matcher; +type UnknownMatcher = PatternMatcher; +export type CustomP = Matcher; +export type ArrayP = Matcher; +export type OptionalP = Matcher; +export type MapP = Matcher; +export type SetP = Matcher; +export type AndP = Matcher; +export type OrP = Matcher; +export type NotP = Matcher; +export type GuardP = Matcher; +export type GuardExcludeP = Matcher; +export type SelectP> = Matcher>; +export type AnonymousSelectP = SelectP; +export interface Override { + [symbols.override]: a; +} +export type UnknownPattern = readonly [] | readonly [unknown, ...unknown[]] | readonly [...unknown[], unknown] | { + readonly [k: string]: unknown; +} | Primitives | UnknownMatcher; +/** + * `Pattern` is the generic type for patterns matching a value of type `a`. A pattern can be any (nested) javascript value. + * + * They can also be wildcards, like `P._`, `P.string`, `P.number`, + * or other matchers, like `P.when(predicate)`, `P.not(pattern)`, etc. + * + * [Read the documentation for `P.Pattern` on GitHub](https://github.com/gvergnaud/ts-pattern#patterns) + * + * @example + * const pattern: P.Pattern = { name: P.string } + */ +export type Pattern = unknown extends a ? UnknownPattern : KnownPattern; +type KnownPattern = KnownPatternInternal; +type KnownPatternInternal | Set | readonly any[]>, arrays = Extract, primitives = Extract> = primitives | PatternMatcher | ([objs] extends [never] ? never : ObjectPattern>>) | ([arrays] extends [never] ? never : ArrayPattern); +type ObjectPattern = { + readonly [k in keyof a]?: Pattern; +} | never; +type ArrayPattern = a extends readonly (infer i)[] ? a extends readonly [any, ...any] ? { + readonly [index in keyof a]: Pattern; +} : readonly [] | readonly [Pattern, ...Pattern[]] | readonly [...Pattern[], Pattern] : never; +export type AnyPattern = Chainable, never>; +export type StringPattern = StringChainable, never>; +export type NumberPattern = NumberChainable, never>; +export type BooleanPattern = Chainable, never>; +export type BigIntPattern = BigIntChainable, never>; +export type SymbolPattern = Chainable, never>; +export type NullishPattern = Chainable, never>; +export type NonNullablePattern = Chainable, never>; +type MergeGuards = [guard1, guard2] extends [ + GuardExcludeP, + GuardExcludeP +] ? GuardExcludeP : never; +export type Chainable = p & Omit<{ + /** + * `.optional()` returns a pattern which matches if the + * key is undefined or if it is defined and the previous pattern matches its value. + * + * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns) + * + * @example + * match(value) + * .with({ greeting: P.string.optional() }, () => 'will match { greeting?: string}') + */ + optional(): Chainable, omitted | 'optional'>; + /** + * `pattern.and(pattern)` returns a pattern that matches + * if the previous pattern and the next one match the input. + * + * [Read the documentation for `P.intersection` on GitHub](https://github.com/gvergnaud/ts-pattern#pintersection-patterns) + * + * @example + * match(value) + * .with( + * P.string.and(P.when(isUsername)), + * (username) => '...' + * ) + */ + and>(pattern: p2): Chainable, omitted>; + /** + * `pattern.or(pattern)` returns a pattern that matches + * if **either** the previous pattern or the next one match the input. + * + * [Read the documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#punion-patterns) + * + * @example + * match(value) + * .with( + * { value: P.string.or(P.number) }, + * ({ value }) => 'value: number | string' + * ) + */ + or>(pattern: p2): Chainable, omitted>; + /** + * `P.select()` will inject this property into the handler function's arguments. + * + * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.string.select() }, (age) => 'age: number') + */ + select(): Chainable, omitted | 'select' | 'or' | 'and'>; + select(key: k): Chainable, omitted | 'select' | 'or' | 'and'>; +}, omitted>; +export type StringChainable

, omitted extends string = never> = Chainable & Omit<{ + /** + * `P.string.startsWith(start)` is a pattern, matching **strings** starting with `start`. + * + * [Read the documentation for `P.string.startsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringstartsWith) + * + * @example + * match(value) + * .with(P.string.startsWith('A'), () => 'value starts with an A') + */ + startsWith(start: start): StringChainable>, omitted | 'startsWith'>; + /** + * `P.string.endsWith(end)` is a pattern, matching **strings** ending with `end`. + * + * [Read the documentation for `P.string.endsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringendsWith) + * + * @example + * match(value) + * .with(P.string.endsWith('!'), () => 'value ends with an !') + */ + endsWith(end: end): StringChainable>, omitted | 'endsWith'>; + /** + * `P.string.minLength(min)` is a pattern, matching **strings** with at least `min` characters. + * + * [Read the documentation for `P.string.minLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringminLength) + * + * @example + * match(value) + * .with(P.string.minLength(10), () => 'string with more length <= 10') + */ + minLength(min: min): StringChainable>, omitted | 'minLength'>; + /** + * `P.string.length(len)` is a pattern, matching **strings** with exactly `len` characters. + * + * [Read the documentation for `P.string.length` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringlength) + * + * @example + * match(value) + * .with(P.string.length(10), () => 'strings with length === 10') + */ + length(len: len): StringChainable>, omitted | 'length' | 'minLength' | 'maxLength'>; + /** + * `P.string.maxLength(max)` is a pattern, matching **strings** with at most `max` characters. + * + * [Read the documentation for `P.string.maxLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringmaxLength) + * + * @example + * match(value) + * .with(P.string.maxLength(10), () => 'string with more length >= 10') + */ + maxLength(max: max): StringChainable>, omitted | 'maxLength'>; + /** + * `P.string.includes(substr)` is a pattern, matching **strings** containing `substr`. + * + * [Read the documentation for `P.string.includes` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringincludes) + * + * @example + * match(value) + * .with(P.string.includes('http'), () => 'value contains http') + */ + includes(substr: substr): StringChainable>, omitted>; + /** + * `P.string.regex(expr)` is a pattern, matching **strings** that `expr` regular expression. + * + * [Read the documentation for `P.string.regex` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringregex) + * + * @example + * match(value) + * .with(P.string.regex(/^https?:\/\//), () => 'url') + */ + regex(expr: expr): StringChainable>, omitted>; +}, omitted>; +export type NumberChainable = Chainable & Omit<{ + /** + * `P.number.between(min, max)` matches **number** between `min` and `max`, + * equal to min or equal to max. + * + * [Read the documentation for `P.number.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween) + * + * @example + * match(value) + * .with(P.number.between(0, 10), () => '0 <= numbers <= 10') + */ + between(min: min, max: max): NumberChainable>, omitted>; + /** + * `P.number.lt(max)` matches **number** smaller than `max`. + * + * [Read the documentation for `P.number.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt) + * + * @example + * match(value) + * .with(P.number.lt(10), () => 'numbers < 10') + */ + lt(max: max): NumberChainable>, omitted>; + /** + * `P.number.gt(min)` matches **number** greater than `min`. + * + * [Read the documentation for `P.number.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt) + * + * @example + * match(value) + * .with(P.number.gt(10), () => 'numbers > 10') + */ + gt(min: min): NumberChainable>, omitted>; + /** + * `P.number.lte(max)` matches **number** smaller than or equal to `max`. + * + * [Read the documentation for `P.number.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte) + * + * @example + * match(value) + * .with(P.number.lte(10), () => 'numbers <= 10') + */ + lte(max: max): NumberChainable>, omitted>; + /** + * `P.number.gte(min)` matches **number** greater than or equal to `min`. + * + * [Read the documentation for `P.number.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergte) + * + * @example + * match(value) + * .with(P.number.gte(10), () => 'numbers >= 10') + */ + gte(min: min): NumberChainable>, omitted>; + /** + * `P.number.int` matches **integer** numbers. + * + * [Read the documentation for `P.number.int` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberint) + * + * @example + * match(value) + * .with(P.number.int, () => 'an integer') + */ + int(): NumberChainable>, omitted | 'int'>; + /** + * `P.number.finite` matches **finite numbers**. + * + * [Read the documentation for `P.number.finite` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberfinite) + * + * @example + * match(value) + * .with(P.number.finite, () => 'not Infinity') + */ + finite(): NumberChainable>, omitted | 'finite'>; + /** + * `P.number.positive` matches **positive** numbers. + * + * [Read the documentation for `P.number.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberpositive) + * + * @example + * match(value) + * .with(P.number.positive, () => 'number > 0') + */ + positive(): NumberChainable>, omitted | 'positive' | 'negative'>; + /** + * `P.number.negative` matches **negative** numbers. + * + * [Read the documentation for `P.number.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbernegative) + * + * @example + * match(value) + * .with(P.number.negative, () => 'number < 0') + */ + negative(): NumberChainable>, omitted | 'positive' | 'negative' | 'negative'>; +}, omitted>; +export type BigIntChainable = Chainable & Omit<{ + /** + * `P.bigint.between(min, max)` matches **bigint** between `min` and `max`, + * equal to min or equal to max. + * + * [Read the documentation for `P.bigint.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween) + * + * @example + * match(value) + * .with(P.bigint.between(0, 10), () => '0 <= numbers <= 10') + */ + between(min: min, max: max): BigIntChainable>, omitted>; + /** + * `P.bigint.lt(max)` matches **bigint** smaller than `max`. + * + * [Read the documentation for `P.bigint.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt) + * + * @example + * match(value) + * .with(P.bigint.lt(10), () => 'numbers < 10') + */ + lt(max: max): BigIntChainable>, omitted>; + /** + * `P.bigint.gt(min)` matches **bigint** greater than `min`. + * + * [Read the documentation for `P.bigint.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt) + * + * @example + * match(value) + * .with(P.bigint.gt(10), () => 'numbers > 10') + */ + gt(min: min): BigIntChainable>, omitted>; + /** + * `P.bigint.lte(max)` matches **bigint** smaller than or equal to `max`. + * + * [Read the documentation for `P.bigint.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte) + * + * @example + * match(value) + * .with(P.bigint.lte(10), () => 'bigints <= 10') + */ + lte(max: max): BigIntChainable>, omitted>; + /** + * `P.bigint.gte(min)` matches **bigint** greater than or equal to `min`. + * + * [Read the documentation for `P.bigint.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergte) + * + * @example + * match(value) + * .with(P.bigint.gte(10), () => 'bigints >= 10') + */ + gte(min: min): BigIntChainable>, omitted>; + /** + * `P.bigint.positive` matches **positive** bigints. + * + * [Read the documentation for `P.bigint.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberpositive) + * + * @example + * match(value) + * .with(P.bigint.positive, () => 'bigint > 0') + */ + positive(): BigIntChainable>, omitted | 'positive' | 'negative'>; + /** + * `P.bigint.negative` matches **negative** bigints. + * + * [Read the documentation for `P.bigint.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbernegative) + * + * @example + * match(value) + * .with(P.bigint.negative, () => 'bigint < 0') + */ + negative(): BigIntChainable>, omitted | 'positive' | 'negative' | 'negative'>; +}, omitted>; +export type Variadic = pattern & Iterable; +export type ArrayChainable = Variadic & Omit<{ + /** + * `.optional()` returns a pattern which matches if the + * key is undefined or if it is defined and the previous pattern matches its value. + * + * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns) + * + * @example + * match(value) + * .with({ greeting: P.string.optional() }, () => 'will match { greeting?: string}') + */ + optional(): ArrayChainable, omitted | 'optional'>; + /** + * `P.select()` will inject this property into the handler function's arguments. + * + * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.string.select() }, (age) => 'age: number') + */ + select(): ArrayChainable, omitted | 'select'>; + select(key: k): ArrayChainable, omitted | 'select'>; +}, omitted>; +export {}; diff --git a/dist/types/Pattern.d.ts b/dist/types/Pattern.d.ts new file mode 100644 index 00000000..f4294124 --- /dev/null +++ b/dist/types/Pattern.d.ts @@ -0,0 +1,396 @@ +import type * as symbols from '../internals/symbols.js'; +import { MergeUnion, Primitives, WithDefault } from './helpers.js'; +import { None, Some, SelectionType } from './FindSelected.js'; +import { matcher } from '../patterns.js'; +import { ExtractPreciseValue } from './ExtractPreciseValue.js'; +export type MatcherType = 'not' | 'optional' | 'or' | 'and' | 'array' | 'map' | 'set' | 'select' | 'default' | 'custom'; +export type MatcherProtocol = { + match: (value: I | input) => MatchResult; + getSelectionKeys?: () => string[]; + matcherType?: matcherType; +}; +export type MatchResult = { + matched: boolean; + selections?: Record; +}; +/** + * A `Matcher` is an object implementing the match + * protocol. It must define a `symbols.matcher` property + * which returns an object with a `match()` method, taking + * the input value and returning whether the pattern matches + * or not, along with optional selections. + */ +export interface Matcher { + [matcher](): MatcherProtocol; + [symbols.isVariadic]?: boolean; +} +type PatternMatcher = Matcher; +export type MatchedValue = WithDefault, a>; +export type AnyMatcher = Matcher; +type UnknownMatcher = PatternMatcher; +export type CustomP = Matcher; +export type ArrayP = Matcher; +export type OptionalP = Matcher; +export type MapP = Matcher; +export type SetP = Matcher; +export type AndP = Matcher; +export type OrP = Matcher; +export type NotP = Matcher; +export type GuardP = Matcher; +export type GuardExcludeP = Matcher; +export type SelectP> = Matcher>; +export type AnonymousSelectP = SelectP; +export interface Override { + [symbols.override]: a; +} +export type UnknownPattern = readonly [] | readonly [unknown, ...unknown[]] | readonly [...unknown[], unknown] | { + readonly [k: string]: unknown; +} | Primitives | UnknownMatcher; +/** + * `Pattern` is the generic type for patterns matching a value of type `a`. A pattern can be any (nested) javascript value. + * + * They can also be wildcards, like `P._`, `P.string`, `P.number`, + * or other matchers, like `P.when(predicate)`, `P.not(pattern)`, etc. + * + * [Read the documentation for `P.Pattern` on GitHub](https://github.com/gvergnaud/ts-pattern#patterns) + * + * @example + * const pattern: P.Pattern = { name: P.string } + */ +export type Pattern = unknown extends a ? UnknownPattern : KnownPattern; +type KnownPattern = KnownPatternInternal; +type KnownPatternInternal | Set | readonly any[]>, arrays = Extract, primitives = Extract> = primitives | PatternMatcher | ([objs] extends [never] ? never : ObjectPattern>>) | ([arrays] extends [never] ? never : ArrayPattern); +type ObjectPattern = { + readonly [k in keyof a]?: Pattern; +} | never; +type ArrayPattern = a extends readonly (infer i)[] ? a extends readonly [any, ...any] ? { + readonly [index in keyof a]: Pattern; +} : readonly [] | readonly [Pattern, ...Pattern[]] | readonly [...Pattern[], Pattern] : never; +export type AnyPattern = Chainable, never>; +export type StringPattern = StringChainable, never>; +export type NumberPattern = NumberChainable, never>; +export type BooleanPattern = Chainable, never>; +export type BigIntPattern = BigIntChainable, never>; +export type SymbolPattern = Chainable, never>; +export type NullishPattern = Chainable, never>; +export type NonNullablePattern = Chainable, never>; +type MergeGuards = [guard1, guard2] extends [ + GuardExcludeP, + GuardExcludeP +] ? GuardExcludeP : never; +export type Chainable = p & Omit<{ + /** + * `.optional()` returns a pattern which matches if the + * key is undefined or if it is defined and the previous pattern matches its value. + * + * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns) + * + * @example + * match(value) + * .with({ greeting: P.string.optional() }, () => 'will match { greeting?: string}') + */ + optional(): Chainable, omitted | 'optional'>; + /** + * `pattern.and(pattern)` returns a pattern that matches + * if the previous pattern and the next one match the input. + * + * [Read the documentation for `P.intersection` on GitHub](https://github.com/gvergnaud/ts-pattern#pintersection-patterns) + * + * @example + * match(value) + * .with( + * P.string.and(P.when(isUsername)), + * (username) => '...' + * ) + */ + and>(pattern: p2): Chainable, omitted>; + /** + * `pattern.or(pattern)` returns a pattern that matches + * if **either** the previous pattern or the next one match the input. + * + * [Read the documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#punion-patterns) + * + * @example + * match(value) + * .with( + * { value: P.string.or(P.number) }, + * ({ value }) => 'value: number | string' + * ) + */ + or>(pattern: p2): Chainable, omitted>; + /** + * `P.select()` will inject this property into the handler function's arguments. + * + * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.string.select() }, (age) => 'age: number') + */ + select(): Chainable, omitted | 'select' | 'or' | 'and'>; + select(key: k): Chainable, omitted | 'select' | 'or' | 'and'>; +}, omitted>; +export type StringChainable

, omitted extends string = never> = Chainable & Omit<{ + /** + * `P.string.startsWith(start)` is a pattern, matching **strings** starting with `start`. + * + * [Read the documentation for `P.string.startsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringstartsWith) + * + * @example + * match(value) + * .with(P.string.startsWith('A'), () => 'value starts with an A') + */ + startsWith(start: start): StringChainable>, omitted | 'startsWith'>; + /** + * `P.string.endsWith(end)` is a pattern, matching **strings** ending with `end`. + * + * [Read the documentation for `P.string.endsWith` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringendsWith) + * + * @example + * match(value) + * .with(P.string.endsWith('!'), () => 'value ends with an !') + */ + endsWith(end: end): StringChainable>, omitted | 'endsWith'>; + /** + * `P.string.minLength(min)` is a pattern, matching **strings** with at least `min` characters. + * + * [Read the documentation for `P.string.minLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringminLength) + * + * @example + * match(value) + * .with(P.string.minLength(10), () => 'string with more length <= 10') + */ + minLength(min: min): StringChainable>, omitted | 'minLength'>; + /** + * `P.string.length(len)` is a pattern, matching **strings** with exactly `len` characters. + * + * [Read the documentation for `P.string.length` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringlength) + * + * @example + * match(value) + * .with(P.string.length(10), () => 'strings with length === 10') + */ + length(len: len): StringChainable>, omitted | 'length' | 'minLength' | 'maxLength'>; + /** + * `P.string.maxLength(max)` is a pattern, matching **strings** with at most `max` characters. + * + * [Read the documentation for `P.string.maxLength` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringmaxLength) + * + * @example + * match(value) + * .with(P.string.maxLength(10), () => 'string with more length >= 10') + */ + maxLength(max: max): StringChainable>, omitted | 'maxLength'>; + /** + * `P.string.includes(substr)` is a pattern, matching **strings** containing `substr`. + * + * [Read the documentation for `P.string.includes` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringincludes) + * + * @example + * match(value) + * .with(P.string.includes('http'), () => 'value contains http') + */ + includes(substr: substr): StringChainable>, omitted>; + /** + * `P.string.regex(expr)` is a pattern, matching **strings** that `expr` regular expression. + * + * [Read the documentation for `P.string.regex` on GitHub](https://github.com/gvergnaud/ts-pattern#pstringregex) + * + * @example + * match(value) + * .with(P.string.regex(/^https?:\/\//), () => 'url') + */ + regex(expr: expr): StringChainable>, omitted>; +}, omitted>; +export type NumberChainable = Chainable & Omit<{ + /** + * `P.number.between(min, max)` matches **number** between `min` and `max`, + * equal to min or equal to max. + * + * [Read the documentation for `P.number.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween) + * + * @example + * match(value) + * .with(P.number.between(0, 10), () => '0 <= numbers <= 10') + */ + between(min: min, max: max): NumberChainable>, omitted>; + /** + * `P.number.lt(max)` matches **number** smaller than `max`. + * + * [Read the documentation for `P.number.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt) + * + * @example + * match(value) + * .with(P.number.lt(10), () => 'numbers < 10') + */ + lt(max: max): NumberChainable>, omitted>; + /** + * `P.number.gt(min)` matches **number** greater than `min`. + * + * [Read the documentation for `P.number.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt) + * + * @example + * match(value) + * .with(P.number.gt(10), () => 'numbers > 10') + */ + gt(min: min): NumberChainable>, omitted>; + /** + * `P.number.lte(max)` matches **number** smaller than or equal to `max`. + * + * [Read the documentation for `P.number.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte) + * + * @example + * match(value) + * .with(P.number.lte(10), () => 'numbers <= 10') + */ + lte(max: max): NumberChainable>, omitted>; + /** + * `P.number.gte(min)` matches **number** greater than or equal to `min`. + * + * [Read the documentation for `P.number.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergte) + * + * @example + * match(value) + * .with(P.number.gte(10), () => 'numbers >= 10') + */ + gte(min: min): NumberChainable>, omitted>; + /** + * `P.number.int` matches **integer** numbers. + * + * [Read the documentation for `P.number.int` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberint) + * + * @example + * match(value) + * .with(P.number.int, () => 'an integer') + */ + int(): NumberChainable>, omitted | 'int'>; + /** + * `P.number.finite` matches **finite numbers**. + * + * [Read the documentation for `P.number.finite` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberfinite) + * + * @example + * match(value) + * .with(P.number.finite, () => 'not Infinity') + */ + finite(): NumberChainable>, omitted | 'finite'>; + /** + * `P.number.positive` matches **positive** numbers. + * + * [Read the documentation for `P.number.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberpositive) + * + * @example + * match(value) + * .with(P.number.positive, () => 'number > 0') + */ + positive(): NumberChainable>, omitted | 'positive' | 'negative'>; + /** + * `P.number.negative` matches **negative** numbers. + * + * [Read the documentation for `P.number.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbernegative) + * + * @example + * match(value) + * .with(P.number.negative, () => 'number < 0') + */ + negative(): NumberChainable>, omitted | 'positive' | 'negative' | 'negative'>; +}, omitted>; +export type BigIntChainable = Chainable & Omit<{ + /** + * `P.bigint.between(min, max)` matches **bigint** between `min` and `max`, + * equal to min or equal to max. + * + * [Read the documentation for `P.bigint.between` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberbetween) + * + * @example + * match(value) + * .with(P.bigint.between(0, 10), () => '0 <= numbers <= 10') + */ + between(min: min, max: max): BigIntChainable>, omitted>; + /** + * `P.bigint.lt(max)` matches **bigint** smaller than `max`. + * + * [Read the documentation for `P.bigint.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlt) + * + * @example + * match(value) + * .with(P.bigint.lt(10), () => 'numbers < 10') + */ + lt(max: max): BigIntChainable>, omitted>; + /** + * `P.bigint.gt(min)` matches **bigint** greater than `min`. + * + * [Read the documentation for `P.bigint.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergt) + * + * @example + * match(value) + * .with(P.bigint.gt(10), () => 'numbers > 10') + */ + gt(min: min): BigIntChainable>, omitted>; + /** + * `P.bigint.lte(max)` matches **bigint** smaller than or equal to `max`. + * + * [Read the documentation for `P.bigint.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberlte) + * + * @example + * match(value) + * .with(P.bigint.lte(10), () => 'bigints <= 10') + */ + lte(max: max): BigIntChainable>, omitted>; + /** + * `P.bigint.gte(min)` matches **bigint** greater than or equal to `min`. + * + * [Read the documentation for `P.bigint.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbergte) + * + * @example + * match(value) + * .with(P.bigint.gte(10), () => 'bigints >= 10') + */ + gte(min: min): BigIntChainable>, omitted>; + /** + * `P.bigint.positive` matches **positive** bigints. + * + * [Read the documentation for `P.bigint.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumberpositive) + * + * @example + * match(value) + * .with(P.bigint.positive, () => 'bigint > 0') + */ + positive(): BigIntChainable>, omitted | 'positive' | 'negative'>; + /** + * `P.bigint.negative` matches **negative** bigints. + * + * [Read the documentation for `P.bigint.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#pnumbernegative) + * + * @example + * match(value) + * .with(P.bigint.negative, () => 'bigint < 0') + */ + negative(): BigIntChainable>, omitted | 'positive' | 'negative' | 'negative'>; +}, omitted>; +export type Variadic = pattern & Iterable; +export type ArrayChainable = Variadic & Omit<{ + /** + * `.optional()` returns a pattern which matches if the + * key is undefined or if it is defined and the previous pattern matches its value. + * + * [Read the documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#poptional-patterns) + * + * @example + * match(value) + * .with({ greeting: P.string.optional() }, () => 'will match { greeting?: string}') + */ + optional(): ArrayChainable, omitted | 'optional'>; + /** + * `P.select()` will inject this property into the handler function's arguments. + * + * [Read the documentation for `P.select` on GitHub](https://github.com/gvergnaud/ts-pattern#pselect-patterns) + * + * @example + * match<{ age: number }>(value) + * .with({ age: P.string.select() }, (age) => 'age: number') + */ + select(): ArrayChainable, omitted | 'select'>; + select(key: k): ArrayChainable, omitted | 'select'>; +}, omitted>; +export {}; diff --git a/dist/types/helpers.d.cts b/dist/types/helpers.d.cts new file mode 100644 index 00000000..fde8a05b --- /dev/null +++ b/dist/types/helpers.d.cts @@ -0,0 +1,77 @@ +export type ValueOf = a extends readonly any[] ? a[number] : a[keyof a]; +export type Values = UnionToTuple>; +/** + * ### LeastUpperBound + * An interesting one. A type taking two imbricated sets and returning the + * smallest one. + * We need that because sometimes the pattern's inferred type holds more + * information than the value on which we are matching (if the value is any + * or unknown for instance). + */ +export type LeastUpperBound = b extends a ? b : a extends b ? a : never; +export type Contains = a extends any ? 'exclude' extends { + [k in keyof a]-?: Equal extends true ? 'exclude' : 'include'; +}[keyof a] ? true : false : never; +export type UnionToIntersection = (union extends any ? (k: union) => void : never) extends (k: infer intersection) => void ? intersection : never; +export type IsUnion = [a] extends [UnionToIntersection] ? false : true; +export type UnionToTuple = UnionToIntersection union : never> extends (_: any) => infer elem ? UnionToTuple, [elem, ...output]> : output; +export type Flatten = xs extends readonly [infer head, ...infer tail] ? Flatten]> : output; +export type Equal = (() => T extends a ? 1 : 2) extends () => T extends b ? 1 : 2 ? true : false; +export type Expect = a; +export type IsAny = 0 extends 1 & a ? true : false; +export type IsNever = [T] extends [never] ? true : false; +export type Length = it['length']; +export type Iterator = it['length'] extends n ? it : Iterator; +export type Next = [any, ...it]; +export type Prev = it extends readonly [any, ...infer tail] ? tail : []; +export type Take = Length extends 0 ? output : xs extends readonly [infer head, ...infer tail] ? Take, [...output, head]> : output; +export type Drop = Length extends 0 ? xs : xs extends readonly [any, ...infer tail] ? Drop> : []; +export type UpdateAt = Length extends 0 ? tail extends readonly [any, ...infer tail] ? [...inits, value, ...tail] : inits : tail extends readonly [infer head, ...infer tail] ? UpdateAt, value, [...inits, head]> : inits; +export type BuiltInObjects = Function | Date | RegExp | Generator | { + readonly [Symbol.toStringTag]: string; +} | any[]; +export type IsPlainObject = o extends object ? o extends string | excludeUnion ? false : true : false; +export type Compute = a extends BuiltInObjects ? a : { + [k in keyof a]: a[k]; +}; +export type IntersectObjects = (a extends any ? keyof a : never) extends infer allKeys ? { + [k in Extract]: a extends any ? k extends keyof a ? a[k] : never : never; +} : never; +export type WithDefault = [a] extends [never] ? def : a; +export type IsLiteral = [a] extends [null | undefined] ? true : [a] extends [string] ? string extends a ? false : true : [a] extends [number] ? number extends a ? false : true : [a] extends [boolean] ? boolean extends a ? false : true : [a] extends [symbol] ? symbol extends a ? false : true : [a] extends [bigint] ? bigint extends a ? false : true : false; +export type Primitives = number | boolean | string | undefined | null | symbol | bigint; +export type NonLiteralPrimitive = Exclude; +export type TupleKeys = '0' | '1' | '2' | '3' | '4'; +export type Union = [b] extends [a] ? a : [a] extends [b] ? b : a | b; +/** + * GuardValue returns the value guarded by a type guard function. + */ +export type GuardValue = fn extends (value: any) => value is infer b ? b : fn extends (value: infer a) => unknown ? a : never; +export type GuardFunction = ((value: input) => value is Extract) | ((value: input) => boolean); +export type Some = true extends bools[number] ? true : false; +export type All = bools[number] extends true ? true : false; +export type Extends = [a] extends [b] ? true : false; +export type Not = a extends true ? false : true; +type AllKeys = a extends any ? keyof a : never; +export type MergeUnion = { + [k in AllKeys]: a extends any ? k extends keyof a ? a[k] : never : never; +} | never; +export type IsFixedSizeTuple = IsLiteral>; +export type IsTuple = a extends readonly [] | readonly [any, ...any] | readonly [...any, any] ? true : false; +export type IsStrictArray = Not>; +export type IsReadonlyArray = a extends readonly any[] ? a extends any[] ? false : true : false; +export type MaybeAddReadonly = shouldAdd extends true ? Readonly : a; +export type MapKey = T extends Map ? K : never; +export type MapValue = T extends Map ? V : never; +export type SetValue = T extends Set ? V : never; +export type ReadonlyArrayValue = T extends ReadonlyArray ? V : never; +export type ExtractPlainObject = T extends any ? IsPlainObject extends true ? T : never : never; +export type GetKey = O extends any ? K extends keyof O ? O[K] : never : never; +export interface Fn { + input: unknown; + output: unknown; +} +export type Call = (fn & { + input: input; +})['output']; +export {}; diff --git a/dist/types/helpers.d.ts b/dist/types/helpers.d.ts new file mode 100644 index 00000000..fde8a05b --- /dev/null +++ b/dist/types/helpers.d.ts @@ -0,0 +1,77 @@ +export type ValueOf = a extends readonly any[] ? a[number] : a[keyof a]; +export type Values = UnionToTuple>; +/** + * ### LeastUpperBound + * An interesting one. A type taking two imbricated sets and returning the + * smallest one. + * We need that because sometimes the pattern's inferred type holds more + * information than the value on which we are matching (if the value is any + * or unknown for instance). + */ +export type LeastUpperBound = b extends a ? b : a extends b ? a : never; +export type Contains = a extends any ? 'exclude' extends { + [k in keyof a]-?: Equal extends true ? 'exclude' : 'include'; +}[keyof a] ? true : false : never; +export type UnionToIntersection = (union extends any ? (k: union) => void : never) extends (k: infer intersection) => void ? intersection : never; +export type IsUnion = [a] extends [UnionToIntersection] ? false : true; +export type UnionToTuple = UnionToIntersection union : never> extends (_: any) => infer elem ? UnionToTuple, [elem, ...output]> : output; +export type Flatten = xs extends readonly [infer head, ...infer tail] ? Flatten]> : output; +export type Equal = (() => T extends a ? 1 : 2) extends () => T extends b ? 1 : 2 ? true : false; +export type Expect = a; +export type IsAny = 0 extends 1 & a ? true : false; +export type IsNever = [T] extends [never] ? true : false; +export type Length = it['length']; +export type Iterator = it['length'] extends n ? it : Iterator; +export type Next = [any, ...it]; +export type Prev = it extends readonly [any, ...infer tail] ? tail : []; +export type Take = Length extends 0 ? output : xs extends readonly [infer head, ...infer tail] ? Take, [...output, head]> : output; +export type Drop = Length extends 0 ? xs : xs extends readonly [any, ...infer tail] ? Drop> : []; +export type UpdateAt = Length extends 0 ? tail extends readonly [any, ...infer tail] ? [...inits, value, ...tail] : inits : tail extends readonly [infer head, ...infer tail] ? UpdateAt, value, [...inits, head]> : inits; +export type BuiltInObjects = Function | Date | RegExp | Generator | { + readonly [Symbol.toStringTag]: string; +} | any[]; +export type IsPlainObject = o extends object ? o extends string | excludeUnion ? false : true : false; +export type Compute = a extends BuiltInObjects ? a : { + [k in keyof a]: a[k]; +}; +export type IntersectObjects = (a extends any ? keyof a : never) extends infer allKeys ? { + [k in Extract]: a extends any ? k extends keyof a ? a[k] : never : never; +} : never; +export type WithDefault = [a] extends [never] ? def : a; +export type IsLiteral = [a] extends [null | undefined] ? true : [a] extends [string] ? string extends a ? false : true : [a] extends [number] ? number extends a ? false : true : [a] extends [boolean] ? boolean extends a ? false : true : [a] extends [symbol] ? symbol extends a ? false : true : [a] extends [bigint] ? bigint extends a ? false : true : false; +export type Primitives = number | boolean | string | undefined | null | symbol | bigint; +export type NonLiteralPrimitive = Exclude; +export type TupleKeys = '0' | '1' | '2' | '3' | '4'; +export type Union = [b] extends [a] ? a : [a] extends [b] ? b : a | b; +/** + * GuardValue returns the value guarded by a type guard function. + */ +export type GuardValue = fn extends (value: any) => value is infer b ? b : fn extends (value: infer a) => unknown ? a : never; +export type GuardFunction = ((value: input) => value is Extract) | ((value: input) => boolean); +export type Some = true extends bools[number] ? true : false; +export type All = bools[number] extends true ? true : false; +export type Extends = [a] extends [b] ? true : false; +export type Not = a extends true ? false : true; +type AllKeys = a extends any ? keyof a : never; +export type MergeUnion = { + [k in AllKeys]: a extends any ? k extends keyof a ? a[k] : never : never; +} | never; +export type IsFixedSizeTuple = IsLiteral>; +export type IsTuple = a extends readonly [] | readonly [any, ...any] | readonly [...any, any] ? true : false; +export type IsStrictArray = Not>; +export type IsReadonlyArray = a extends readonly any[] ? a extends any[] ? false : true : false; +export type MaybeAddReadonly = shouldAdd extends true ? Readonly : a; +export type MapKey = T extends Map ? K : never; +export type MapValue = T extends Map ? V : never; +export type SetValue = T extends Set ? V : never; +export type ReadonlyArrayValue = T extends ReadonlyArray ? V : never; +export type ExtractPlainObject = T extends any ? IsPlainObject extends true ? T : never : never; +export type GetKey = O extends any ? K extends keyof O ? O[K] : never : never; +export interface Fn { + input: unknown; + output: unknown; +} +export type Call = (fn & { + input: input; +})['output']; +export {}; diff --git a/dist/types/index.d.cts b/dist/types/index.d.cts new file mode 100644 index 00000000..c7efc320 --- /dev/null +++ b/dist/types/index.d.cts @@ -0,0 +1,6 @@ +export * from './ExtractPreciseValue.cjs'; +export * from './FindSelected.cjs'; +export * from './InvertPattern.cjs'; +export * from './IsMatching.cjs'; +export * from './Match.cjs'; +export * from './Pattern.cjs'; diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts new file mode 100644 index 00000000..f20b4f62 --- /dev/null +++ b/dist/types/index.d.ts @@ -0,0 +1,6 @@ +export * from './ExtractPreciseValue.js'; +export * from './FindSelected.js'; +export * from './InvertPattern.js'; +export * from './IsMatching.js'; +export * from './Match.js'; +export * from './Pattern.js';