ts-pattern
Advanced tools
Comparing version 4.3.0 to 5.0.0-rc.0
@@ -1,2 +0,2 @@ | ||
var n=Symbol("@ts-pattern/matcher"),t="@ts-pattern/anonymous-select-key",e=function(n){return Boolean(n&&"object"==typeof n)},r=function(t){return t&&!!t[n]},u=function t(u,i,c){if(e(u)){if(r(u)){var o=u[n]().match(i),a=o.matched,f=o.selections;return a&&f&&Object.keys(f).forEach(function(n){return c(n,f[n])}),a}if(!e(i))return!1;if(Array.isArray(u))return!!Array.isArray(i)&&u.length===i.length&&u.every(function(n,e){return t(n,i[e],c)});if(u instanceof Map)return i instanceof Map&&Array.from(u.keys()).every(function(n){return t(u.get(n),i.get(n),c)});if(u instanceof Set){if(!(i instanceof Set))return!1;if(0===u.size)return 0===i.size;if(1===u.size){var s=Array.from(u.values())[0];return r(s)?Array.from(i.values()).every(function(n){return t(s,n,c)}):i.has(s)}return Array.from(u.values()).every(function(n){return i.has(n)})}return Object.keys(u).every(function(e){var o,a=u[e];return(e in i||r(o=a)&&"optional"===o[n]().matcherType)&&t(a,i[e],c)})}return Object.is(i,u)},i=function t(u){var i,o,a;return e(u)?r(u)?null!=(i=null==(o=(a=u[n]()).getSelectionKeys)?void 0:o.call(a))?i:[]:Array.isArray(u)?c(u,t):c(Object.values(u),t):[]},c=function(n,t){return n.reduce(function(n,e){return n.concat(t(e))},[])};function o(t){var e;return(e={})[n]=function(){return{match:function(n){var e={},r=function(n,t){e[n]=t};return void 0===n?(i(t).forEach(function(n){return r(n,void 0)}),{matched:!0,selections:e}):{matched:u(t,n,r),selections:e}},getSelectionKeys:function(){return i(t)},matcherType:"optional"}},e}function a(t){var e;return(e={})[n]=function(){return{match:function(n){if(!Array.isArray(n))return{matched:!1};var e={};if(0===n.length)return i(t).forEach(function(n){e[n]=[]}),{matched:!0,selections:e};var r=function(n,t){e[n]=(e[n]||[]).concat([t])};return{matched:n.every(function(n){return u(t,n,r)}),selections:e}},getSelectionKeys:function(){return i(t)}}},e}function f(){var t,e=[].slice.call(arguments);return(t={})[n]=function(){return{match:function(n){var t={},r=function(n,e){t[n]=e};return{matched:e.every(function(t){return u(t,n,r)}),selections:t}},getSelectionKeys:function(){return c(e,i)},matcherType:"and"}},t}function s(){var t,e=[].slice.call(arguments);return(t={})[n]=function(){return{match:function(n){var t={},r=function(n,e){t[n]=e};return c(e,i).forEach(function(n){return r(n,void 0)}),{matched:e.some(function(t){return u(t,n,r)}),selections:t}},getSelectionKeys:function(){return c(e,i)},matcherType:"or"}},t}function l(t){var e;return(e={})[n]=function(){return{match:function(n){return{matched:!u(t,n,function(){})}},getSelectionKeys:function(){return[]},matcherType:"not"}},e}function h(t){var e;return(e={})[n]=function(){return{match:function(n){return{matched:Boolean(t(n))}}}},e}function v(){var e,r=[].slice.call(arguments),c="string"==typeof r[0]?r[0]:void 0,o=2===r.length?r[1]:"string"==typeof r[0]?void 0:r[0];return(e={})[n]=function(){return{match:function(n){var e,r=((e={})[null!=c?c:t]=n,e);return{matched:void 0===o||u(o,n,function(n,t){r[n]=t}),selections:r}},getSelectionKeys:function(){return[null!=c?c:t].concat(void 0===o?[]:i(o))}}},e}var y=h(function(n){return!0}),m=y,d=h(function(n){return"string"==typeof n}),g=h(function(n){return"number"==typeof n}),p=h(function(n){return"boolean"==typeof n}),b=h(function(n){return"bigint"==typeof n}),w=h(function(n){return"symbol"==typeof n}),A=h(function(n){return null==n}),S={__proto__:null,optional:o,array:a,intersection:f,union:s,not:l,when:h,select:v,any:y,_:m,string:d,number:g,boolean:p,bigint:b,symbol:w,nullish:A,instanceOf:function(n){return h(function(n){return function(t){return t instanceof n}}(n))},typed:function(){return{array:a,optional:o,intersection:f,union:s,not:l,select:v,when:h}}};function K(n){return new O(n,[])}var O=/*#__PURE__*/function(){function n(n,t){this.value=void 0,this.cases=void 0,this.value=n,this.cases=t}var e=n.prototype;return e.with=function(){var e=[].slice.call(arguments),r=e[e.length-1],i=[e[0]],c=[];return 3===e.length&&"function"==typeof e[1]?(i.push(e[0]),c.push(e[1])):e.length>2&&i.push.apply(i,e.slice(1,e.length-1)),new n(this.value,this.cases.concat([{match:function(n){var e={},r=Boolean(i.some(function(t){return u(t,n,function(n,t){e[n]=t})})&&c.every(function(t){return t(n)}));return{matched:r,value:r&&Object.keys(e).length?t in e?e[t]:e:n}},handler:r}]))},e.when=function(t,e){return new n(this.value,this.cases.concat([{match:function(n){return{matched:Boolean(t(n)),value:n}},handler:e}]))},e.otherwise=function(t){return new n(this.value,this.cases.concat([{match:function(n){return{matched:!0,value:n}},handler:t}])).run()},e.exhaustive=function(){return this.run()},e.run=function(){for(var n=this.value,t=void 0,e=0;e<this.cases.length;e++){var r=this.cases[e],u=r.match(this.value);if(u.matched){n=u.value,t=r.handler;break}}if(!t){var i;try{i=JSON.stringify(this.value)}catch(n){i=this.value}throw new Error("Pattern matching error: no pattern matches value "+i)}return t(n,this.value)},n}();function j(){var n=[].slice.call(arguments);if(1===n.length){var t=n[0];return function(n){return u(t,n,function(){})}}if(2===n.length)return u(n[0],n[1],function(){});throw new Error("isMatching wasn't given the right number of arguments: expected 1 or 2, received "+n.length+".")}export{S as P,S as Pattern,j as isMatching,K as match}; | ||
function n(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e<t;e++)r[e]=n[e];return r}function t(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(r)return(r=r.call(t)).next.bind(r);if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return n(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var u=0;return function(){return u>=t.length?{done:!0}:{done:!1,value:t[u++]}}}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 e=Symbol("@ts-pattern/matcher"),r=Symbol("@ts-pattern/isVariadic"),u="@ts-pattern/anonymous-select-key",i=function(n){return Boolean(n&&"object"==typeof n)},o=function(n){return n&&!!n[e]},c=function n(u,c,a){if(o(u)){var f=u[e]().match(c),s=f.matched,l=f.selections;return s&&l&&Object.keys(l).forEach(function(n){return a(n,l[n])}),s}if(i(u)){if(!i(c))return!1;if(Array.isArray(u)){if(!Array.isArray(c))return!1;for(var h,v=[],g=[],m=[],p=t(u.keys());!(h=p()).done;){var y=u[h.value];o(y)&&y[r]?m.push(y):m.length?g.push(y):v.push(y)}if(m.length){if(m.length>1)throw new Error("Pattern error: Using `...P.array(...)` several time in a single pattern is not allowed.");if(c.length<v.length+g.length)return!1;var d=c.slice(0,v.length),b=0===g.length?[]:c.slice(-g.length),w=c.slice(v.length,0===g.length?Infinity:-g.length);return v.every(function(t,e){return n(t,d[e],a)})&&g.every(function(t,e){return n(t,b[e],a)})&&(0===m.length||n(m[0],w,a))}return u.length===c.length&&u.every(function(t,e){return n(t,c[e],a)})}return Object.keys(u).every(function(t){var r,i=u[t];return(t in c||o(r=i)&&"optional"===r[e]().matcherType)&&n(i,c[t],a)})}return Object.is(c,u)},a=function n(t){var r,u,c;return i(t)?o(t)?null!=(r=null==(u=(c=t[e]()).getSelectionKeys)?void 0:u.call(c))?r:[]:Array.isArray(t)?f(t,n):f(Object.values(t),n):[]},f=function(n,t){return n.reduce(function(n,e){return n.concat(t(e))},[])};function s(){var n=[].slice.call(arguments);if(1===n.length){var t=n[0];return function(n){return c(t,n,function(){})}}if(2===n.length)return c(n[0],n[1],function(){});throw new Error("isMatching wasn't given the right number of arguments: expected 1 or 2, received "+n.length+".")}var l=function(n){return Object.assign(n,{optional:function(){return h(n)},and:function(t){return p(n,t)},or:function(t){return y(n,t)},select:function(t){return void 0===t?w(n):w(t,n)}})};function h(n){var t;return l(((t={})[e]=function(){return{match:function(t){var e={},r=function(n,t){e[n]=t};return void 0===t?(a(n).forEach(function(n){return r(n,void 0)}),{matched:!0,selections:e}):{matched:c(n,t,r),selections:e}},getSelectionKeys:function(){return a(n)},matcherType:"optional"}},t))}function v(){var n,t=[].slice.call(arguments);return l(((n={})[e]=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 a(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 c(e,n,u)}),selections:r}},getSelectionKeys:function(){return 0===t.length?[]:a(t[0])}}},n[Symbol.iterator]=function(){/*#__PURE__*/return regeneratorRuntime.mark(function n(){var e;return regeneratorRuntime.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,Object.assign(0===t.length?v():v(t[0]),((e={})[r]=!0,e));case 2:case"end":return n.stop()}},n)})()},n))}var g=function(n,e){for(var r,u=t(n);!(r=u()).done;)if(!e(r.value))return!1;return!0},m=function(n,e){for(var r,u=t(n.entries());!(r=u()).done;){var i=r.value;if(!e(i[1],i[0]))return!1}return!0};function p(){var n,t=[].slice.call(arguments);return l(((n={})[e]=function(){return{match:function(n){var e={},r=function(n,t){e[n]=t};return{matched:t.every(function(t){return c(t,n,r)}),selections:e}},getSelectionKeys:function(){return f(t,a)},matcherType:"and"}},n))}function y(){var n,t=[].slice.call(arguments);return l(((n={})[e]=function(){return{match:function(n){var e={},r=function(n,t){e[n]=t};return f(t,a).forEach(function(n){return r(n,void 0)}),{matched:t.some(function(t){return c(t,n,r)}),selections:e}},getSelectionKeys:function(){return f(t,a)},matcherType:"or"}},n))}function d(n){var t;return l(((t={})[e]=function(){return{match:function(t){return{matched:!c(n,t,function(){})}},getSelectionKeys:function(){return[]},matcherType:"not"}},t))}function b(n){var t;return l(((t={})[e]=function(){return{match:function(t){return{matched:Boolean(n(t))}}}},t))}function w(){var n,t=[].slice.call(arguments),r="string"==typeof t[0]?t[0]:void 0,i=2===t.length?t[1]:"string"==typeof t[0]?void 0:t[0];return l(((n={})[e]=function(){return{match:function(n){var t,e=((t={})[null!=r?r:u]=n,t);return{matched:void 0===i||c(i,n,function(n,t){e[n]=t}),selections:e}},getSelectionKeys:function(){return[null!=r?r:u].concat(void 0===i?[]:a(i))}}},n))}function S(n){return"number"==typeof n}function j(n){return"string"==typeof n}function A(n){return"bigint"==typeof n}var O=l(b(function(n){return!0})),B=O,I=function n(t){return Object.assign(t,{startsWith:function(e){return n(p(t,(r=e,b(function(n){return j(n)&&n.startsWith(r)}))));var r},endsWith:function(e){return n(p(t,(r=e,b(function(n){return j(n)&&n.endsWith(r)}))));var r},includes:function(e){return n(p(t,(r=e,b(function(n){return j(n)&&n.includes(r)}))));var r},regex:function(e){return n(p(t,(r=e,b(function(n){return j(n)&&Boolean(n.match(r))}))));var r}})}(b(j)),E=function(n,t){return b(function(e){return S(e)&&n<=e&&t>=e})},K=function(n){return b(function(t){return S(t)&&t<n})},x=function(n){return b(function(t){return S(t)&&t>n})},k=function(n){return b(function(t){return S(t)&&t<=n})},T=function(n){return b(function(t){return S(t)&&t>=n})},P=function(){return b(function(n){return S(n)&&Number.isInteger(n)})},_=function(){return b(function(n){return S(n)&&Number.isFinite(n)})},W=function(){return b(function(n){return S(n)&&n>0})},M=function(){return b(function(n){return S(n)&&n<0})},N=function n(t){return Object.assign(t,{between:function(e,r){return n(p(t,E(e,r)))},lt:function(e){return n(p(t,K(e)))},gt:function(e){return n(p(t,x(e)))},lte:function(e){return n(p(t,k(e)))},gte:function(e){return n(p(t,T(e)))},int:function(){return n(p(t,P()))},finite:function(){return n(p(t,_()))},positive:function(){return n(p(t,W()))},negative:function(){return n(p(t,M()))}})}(b(S)),z=function(n,t){return b(function(e){return A(e)&&n<=e&&t>=e})},R=function(n){return b(function(t){return A(t)&&t<n})},U=function(n){return b(function(t){return A(t)&&t>n})},C=function(n){return b(function(t){return A(t)&&t<=n})},F=function(n){return b(function(t){return A(t)&&t>=n})},J=function(){return b(function(n){return A(n)&&n>0})},V=function(){return b(function(n){return A(n)&&n<0})},$=function n(t){return Object.assign(t,{between:function(e,r){return n(p(t,z(e,r)))},lt:function(e){return n(p(t,R(e)))},gt:function(e){return n(p(t,U(e)))},lte:function(e){return n(p(t,C(e)))},gte:function(e){return n(p(t,F(e)))},positive:function(){return n(p(t,J()))},negative:function(){return n(p(t,V()))}})}(b(A)),q=l(b(function(n){return"boolean"==typeof n})),D=l(b(function(n){return"symbol"==typeof n})),G=l(b(function(n){return null==n})),H={__proto__:null,matcher:e,optional:h,array:v,set:function(){var n,t=[].slice.call(arguments);return l(((n={})[e]=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:g(n,function(n){return c(u,n,r)}),selections:e}},getSelectionKeys:function(){return 0===t.length?[]:a(t[0])}}},n))},map:function(){var n,t=[].slice.call(arguments);return l(((n={})[e]=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:m(n,function(n,t){var e=c(i,t,u),r=c(o,n,u);return e&&r}),selections:e}},getSelectionKeys:function(){return 0===t.length?[]:[].concat(a(t[0]),a(t[1]))}}},n))},intersection:p,union:y,not:d,when:b,select:w,any:O,_:B,string:I,between:E,lt:K,gt:x,lte:k,gte:T,int:P,finite:_,positive:W,negative:M,number:N,betweenBigInt:z,ltBigInt:R,gtBigInt:U,lteBigInt:C,gteBigInt:F,positiveBigInt:J,negativeBigInt:V,bigint:$,boolean:q,symbol:D,nullish:G,instanceOf:function(n){return l(b(function(n){return function(t){return t instanceof n}}(n)))},shape:function(n){return l(b(s(n)))},typed:function(){return{array:v,optional:h,intersection:p,union:y,not:d,select:w,when:b}}};function L(n){return new X(n)}var Q={matched:!1},X=/*#__PURE__*/function(){function n(n,t){void 0===t&&(t=Q),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],i=[e[0]],o=[];3===e.length&&"function"==typeof e[1]?(i.push(e[0]),o.push(e[1])):e.length>2&&i.push.apply(i,e.slice(1,e.length-1));var a={},f=Boolean(i.some(function(n){return c(n,t.input,function(n,t){a[n]=t})})&&o.every(function(n){return n(t.input)}))?{matched:!0,value:r(Object.keys(a).length?u in a?a[u]:a:this.input,this.input)}:{matched:!1};return new n(this.input,f)},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)}:{matched:!1})},t.otherwise=function(n){return this.state.matched?this.state.value:n(this.input,this.input)},t.exhaustive=function(){return this.run()},t.run=function(){if(this.state.matched)return this.state.value;var n;try{n=JSON.stringify(this.input)}catch(t){n=this.input}throw new Error("Pattern matching error: no pattern matches value "+n)},t.returnType=function(){return this},n}();export{H as P,H as Pattern,s as isMatching,L as match}; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,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){var t=Symbol("@ts-pattern/matcher"),e="@ts-pattern/anonymous-select-key",r=function(n){return Boolean(n&&"object"==typeof n)},u=function(n){return n&&!!n[t]},i=function n(e,i,o){if(r(e)){if(u(e)){var c=e[t]().match(i),a=c.matched,f=c.selections;return a&&f&&Object.keys(f).forEach(function(n){return o(n,f[n])}),a}if(!r(i))return!1;if(Array.isArray(e))return!!Array.isArray(i)&&e.length===i.length&&e.every(function(t,e){return n(t,i[e],o)});if(e instanceof Map)return i instanceof Map&&Array.from(e.keys()).every(function(t){return n(e.get(t),i.get(t),o)});if(e instanceof Set){if(!(i instanceof Set))return!1;if(0===e.size)return 0===i.size;if(1===e.size){var s=Array.from(e.values())[0];return u(s)?Array.from(i.values()).every(function(t){return n(s,t,o)}):i.has(s)}return Array.from(e.values()).every(function(n){return i.has(n)})}return Object.keys(e).every(function(r){var c,a=e[r];return(r in i||u(c=a)&&"optional"===c[t]().matcherType)&&n(a,i[r],o)})}return Object.is(i,e)},o=function n(e){var i,o,a;return r(e)?u(e)?null!=(i=null==(o=(a=e[t]()).getSelectionKeys)?void 0:o.call(a))?i:[]:Array.isArray(e)?c(e,n):c(Object.values(e),n):[]},c=function(n,t){return n.reduce(function(n,e){return n.concat(t(e))},[])};function a(n){var e;return(e={})[t]=function(){return{match:function(t){var e={},r=function(n,t){e[n]=t};return void 0===t?(o(n).forEach(function(n){return r(n,void 0)}),{matched:!0,selections:e}):{matched:i(n,t,r),selections:e}},getSelectionKeys:function(){return o(n)},matcherType:"optional"}},e}function f(n){var e;return(e={})[t]=function(){return{match:function(t){if(!Array.isArray(t))return{matched:!1};var e={};if(0===t.length)return o(n).forEach(function(n){e[n]=[]}),{matched:!0,selections:e};var r=function(n,t){e[n]=(e[n]||[]).concat([t])};return{matched:t.every(function(t){return i(n,t,r)}),selections:e}},getSelectionKeys:function(){return o(n)}}},e}function s(){var n,e=[].slice.call(arguments);return(n={})[t]=function(){return{match:function(n){var t={},r=function(n,e){t[n]=e};return{matched:e.every(function(t){return i(t,n,r)}),selections:t}},getSelectionKeys:function(){return c(e,o)},matcherType:"and"}},n}function l(){var n,e=[].slice.call(arguments);return(n={})[t]=function(){return{match:function(n){var t={},r=function(n,e){t[n]=e};return c(e,o).forEach(function(n){return r(n,void 0)}),{matched:e.some(function(t){return i(t,n,r)}),selections:t}},getSelectionKeys:function(){return c(e,o)},matcherType:"or"}},n}function h(n){var e;return(e={})[t]=function(){return{match:function(t){return{matched:!i(n,t,function(){})}},getSelectionKeys:function(){return[]},matcherType:"not"}},e}function v(n){var e;return(e={})[t]=function(){return{match:function(t){return{matched:Boolean(n(t))}}}},e}function y(){var n,r=[].slice.call(arguments),u="string"==typeof r[0]?r[0]:void 0,c=2===r.length?r[1]:"string"==typeof r[0]?void 0:r[0];return(n={})[t]=function(){return{match:function(n){var t,r=((t={})[null!=u?u:e]=n,t);return{matched:void 0===c||i(c,n,function(n,t){r[n]=t}),selections:r}},getSelectionKeys:function(){return[null!=u?u:e].concat(void 0===c?[]:o(c))}}},n}var m=v(function(n){return!0}),d=m,p=v(function(n){return"string"==typeof n}),g=v(function(n){return"number"==typeof n}),b=v(function(n){return"boolean"==typeof n}),w=v(function(n){return"bigint"==typeof n}),A=v(function(n){return"symbol"==typeof n}),S=v(function(n){return null==n}),j={__proto__:null,optional:a,array:f,intersection:s,union:l,not:h,when:v,select:y,any:m,_:d,string:p,number:g,boolean:b,bigint:w,symbol:A,nullish:S,instanceOf:function(n){return v(function(n){return function(t){return t instanceof n}}(n))},typed:function(){return{array:f,optional:a,intersection:s,union:l,not:h,select:y,when:v}}},K=/*#__PURE__*/function(){function n(n,t){this.value=void 0,this.cases=void 0,this.value=n,this.cases=t}var t=n.prototype;return t.with=function(){var t=[].slice.call(arguments),r=t[t.length-1],u=[t[0]],o=[];return 3===t.length&&"function"==typeof t[1]?(u.push(t[0]),o.push(t[1])):t.length>2&&u.push.apply(u,t.slice(1,t.length-1)),new n(this.value,this.cases.concat([{match:function(n){var t={},r=Boolean(u.some(function(e){return i(e,n,function(n,e){t[n]=e})})&&o.every(function(t){return t(n)}));return{matched:r,value:r&&Object.keys(t).length?e in t?t[e]:t:n}},handler:r}]))},t.when=function(t,e){return new n(this.value,this.cases.concat([{match:function(n){return{matched:Boolean(t(n)),value:n}},handler:e}]))},t.otherwise=function(t){return new n(this.value,this.cases.concat([{match:function(n){return{matched:!0,value:n}},handler:t}])).run()},t.exhaustive=function(){return this.run()},t.run=function(){for(var n=this.value,t=void 0,e=0;e<this.cases.length;e++){var r=this.cases[e],u=r.match(this.value);if(u.matched){n=u.value,t=r.handler;break}}if(!t){var i;try{i=JSON.stringify(this.value)}catch(n){i=this.value}throw new Error("Pattern matching error: no pattern matches value "+i)}return t(n,this.value)},n}();n.P=j,n.Pattern=j,n.isMatching=function(){var n=[].slice.call(arguments);if(1===n.length){var t=n[0];return function(n){return i(t,n,function(){})}}if(2===n.length)return i(n[0],n[1],function(){});throw new Error("isMatching wasn't given the right number of arguments: expected 1 or 2, received "+n.length+".")},n.match=function(n){return new K(n,[])}}); | ||
!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,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e<t;e++)r[e]=n[e];return r}function e(n,e){var r="undefined"!=typeof Symbol&&n[Symbol.iterator]||n["@@iterator"];if(r)return(r=r.call(n)).next.bind(r);if(Array.isArray(n)||(r=function(n,e){if(n){if("string"==typeof n)return t(n,e);var r=Object.prototype.toString.call(n).slice(8,-1);return"Object"===r&&n.constructor&&(r=n.constructor.name),"Map"===r||"Set"===r?Array.from(n):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?t(n,e):void 0}}(n))||e&&n&&"number"==typeof n.length){r&&(n=r);var i=0;return function(){return i>=n.length?{done:!0}:{done:!1,value:n[i++]}}}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 r=Symbol("@ts-pattern/matcher"),i=Symbol("@ts-pattern/isVariadic"),u="@ts-pattern/anonymous-select-key",o=function(n){return Boolean(n&&"object"==typeof n)},c=function(n){return n&&!!n[r]},a=function n(t,u,a){if(c(t)){var f=t[r]().match(u),s=f.matched,l=f.selections;return s&&l&&Object.keys(l).forEach(function(n){return a(n,l[n])}),s}if(o(t)){if(!o(u))return!1;if(Array.isArray(t)){if(!Array.isArray(u))return!1;for(var h,v=[],g=[],m=[],p=e(t.keys());!(h=p()).done;){var d=t[h.value];c(d)&&d[i]?m.push(d):m.length?g.push(d):v.push(d)}if(m.length){if(m.length>1)throw new Error("Pattern error: Using `...P.array(...)` several time in a single pattern is not allowed.");if(u.length<v.length+g.length)return!1;var y=u.slice(0,v.length),b=0===g.length?[]:u.slice(-g.length),w=u.slice(v.length,0===g.length?Infinity:-g.length);return v.every(function(t,e){return n(t,y[e],a)})&&g.every(function(t,e){return n(t,b[e],a)})&&(0===m.length||n(m[0],w,a))}return t.length===u.length&&t.every(function(t,e){return n(t,u[e],a)})}return Object.keys(t).every(function(e){var i,o=t[e];return(e in u||c(i=o)&&"optional"===i[r]().matcherType)&&n(o,u[e],a)})}return Object.is(u,t)},f=function n(t){var e,i,u;return o(t)?c(t)?null!=(e=null==(i=(u=t[r]()).getSelectionKeys)?void 0:i.call(u))?e:[]:Array.isArray(t)?s(t,n):s(Object.values(t),n):[]},s=function(n,t){return n.reduce(function(n,e){return n.concat(t(e))},[])};function l(){var n=[].slice.call(arguments);if(1===n.length){var t=n[0];return function(n){return a(t,n,function(){})}}if(2===n.length)return a(n[0],n[1],function(){});throw new Error("isMatching wasn't given the right number of arguments: expected 1 or 2, received "+n.length+".")}var h=function(n){return Object.assign(n,{optional:function(){return v(n)},and:function(t){return d(n,t)},or:function(t){return y(n,t)},select:function(t){return void 0===t?S(n):S(t,n)}})};function v(n){var t;return h(((t={})[r]=function(){return{match:function(t){var e={},r=function(n,t){e[n]=t};return void 0===t?(f(n).forEach(function(n){return r(n,void 0)}),{matched:!0,selections:e}):{matched:a(n,t,r),selections:e}},getSelectionKeys:function(){return f(n)},matcherType:"optional"}},t))}function g(){var n,t=[].slice.call(arguments);return h(((n={})[r]=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 f(e).forEach(function(n){r[n]=[]}),{matched:!0,selections:r};var i=function(n,t){r[n]=(r[n]||[]).concat([t])};return{matched:n.every(function(n){return a(e,n,i)}),selections:r}},getSelectionKeys:function(){return 0===t.length?[]:f(t[0])}}},n[Symbol.iterator]=function(){/*#__PURE__*/return regeneratorRuntime.mark(function n(){var e;return regeneratorRuntime.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return n.next=2,Object.assign(0===t.length?g():g(t[0]),((e={})[i]=!0,e));case 2:case"end":return n.stop()}},n)})()},n))}var m=function(n,t){for(var r,i=e(n);!(r=i()).done;)if(!t(r.value))return!1;return!0},p=function(n,t){for(var r,i=e(n.entries());!(r=i()).done;){var u=r.value;if(!t(u[1],u[0]))return!1}return!0};function d(){var n,t=[].slice.call(arguments);return h(((n={})[r]=function(){return{match:function(n){var e={},r=function(n,t){e[n]=t};return{matched:t.every(function(t){return a(t,n,r)}),selections:e}},getSelectionKeys:function(){return s(t,f)},matcherType:"and"}},n))}function y(){var n,t=[].slice.call(arguments);return h(((n={})[r]=function(){return{match:function(n){var e={},r=function(n,t){e[n]=t};return s(t,f).forEach(function(n){return r(n,void 0)}),{matched:t.some(function(t){return a(t,n,r)}),selections:e}},getSelectionKeys:function(){return s(t,f)},matcherType:"or"}},n))}function b(n){var t;return h(((t={})[r]=function(){return{match:function(t){return{matched:!a(n,t,function(){})}},getSelectionKeys:function(){return[]},matcherType:"not"}},t))}function w(n){var t;return h(((t={})[r]=function(){return{match:function(t){return{matched:Boolean(n(t))}}}},t))}function S(){var n,t=[].slice.call(arguments),e="string"==typeof t[0]?t[0]:void 0,i=2===t.length?t[1]:"string"==typeof t[0]?void 0:t[0];return h(((n={})[r]=function(){return{match:function(n){var t,r=((t={})[null!=e?e:u]=n,t);return{matched:void 0===i||a(i,n,function(n,t){r[n]=t}),selections:r}},getSelectionKeys:function(){return[null!=e?e:u].concat(void 0===i?[]:f(i))}}},n))}function j(n){return"number"==typeof n}function A(n){return"string"==typeof n}function O(n){return"bigint"==typeof n}var B=h(w(function(n){return!0})),I=B,x=function n(t){return Object.assign(t,{startsWith:function(e){return n(d(t,(r=e,w(function(n){return A(n)&&n.startsWith(r)}))));var r},endsWith:function(e){return n(d(t,(r=e,w(function(n){return A(n)&&n.endsWith(r)}))));var r},includes:function(e){return n(d(t,(r=e,w(function(n){return A(n)&&n.includes(r)}))));var r},regex:function(e){return n(d(t,(r=e,w(function(n){return A(n)&&Boolean(n.match(r))}))));var r}})}(w(A)),E=function(n,t){return w(function(e){return j(e)&&n<=e&&t>=e})},K=function(n){return w(function(t){return j(t)&&t<n})},T=function(n){return w(function(t){return j(t)&&t>n})},k=function(n){return w(function(t){return j(t)&&t<=n})},P=function(n){return w(function(t){return j(t)&&t>=n})},_=function(){return w(function(n){return j(n)&&Number.isInteger(n)})},M=function(){return w(function(n){return j(n)&&Number.isFinite(n)})},W=function(){return w(function(n){return j(n)&&n>0})},N=function(){return w(function(n){return j(n)&&n<0})},z=function n(t){return Object.assign(t,{between:function(e,r){return n(d(t,E(e,r)))},lt:function(e){return n(d(t,K(e)))},gt:function(e){return n(d(t,T(e)))},lte:function(e){return n(d(t,k(e)))},gte:function(e){return n(d(t,P(e)))},int:function(){return n(d(t,_()))},finite:function(){return n(d(t,M()))},positive:function(){return n(d(t,W()))},negative:function(){return n(d(t,N()))}})}(w(j)),R=function(n,t){return w(function(e){return O(e)&&n<=e&&t>=e})},U=function(n){return w(function(t){return O(t)&&t<n})},C=function(n){return w(function(t){return O(t)&&t>n})},F=function(n){return w(function(t){return O(t)&&t<=n})},J=function(n){return w(function(t){return O(t)&&t>=n})},V=function(){return w(function(n){return O(n)&&n>0})},$=function(){return w(function(n){return O(n)&&n<0})},q=function n(t){return Object.assign(t,{between:function(e,r){return n(d(t,R(e,r)))},lt:function(e){return n(d(t,U(e)))},gt:function(e){return n(d(t,C(e)))},lte:function(e){return n(d(t,F(e)))},gte:function(e){return n(d(t,J(e)))},positive:function(){return n(d(t,V()))},negative:function(){return n(d(t,$()))}})}(w(O)),D=h(w(function(n){return"boolean"==typeof n})),G=h(w(function(n){return"symbol"==typeof n})),H=h(w(function(n){return null==n})),L={__proto__:null,matcher:r,optional:v,array:g,set:function(){var n,t=[].slice.call(arguments);return h(((n={})[r]=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])},i=t[0];return{matched:m(n,function(n){return a(i,n,r)}),selections:e}},getSelectionKeys:function(){return 0===t.length?[]:f(t[0])}}},n))},map:function(){var n,t=[].slice.call(arguments);return h(((n={})[r]=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,i=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 u=t[0],o=t[1];return{matched:p(n,function(n,t){var e=a(u,t,i),r=a(o,n,i);return e&&r}),selections:e}},getSelectionKeys:function(){return 0===t.length?[]:[].concat(f(t[0]),f(t[1]))}}},n))},intersection:d,union:y,not:b,when:w,select:S,any:B,_:I,string:x,between:E,lt:K,gt:T,lte:k,gte:P,int:_,finite:M,positive:W,negative:N,number:z,betweenBigInt:R,ltBigInt:U,gtBigInt:C,lteBigInt:F,gteBigInt:J,positiveBigInt:V,negativeBigInt:$,bigint:q,boolean:D,symbol:G,nullish:H,instanceOf:function(n){return h(w(function(n){return function(t){return t instanceof n}}(n)))},shape:function(n){return h(w(l(n)))},typed:function(){return{array:g,optional:v,intersection:d,union:y,not:b,select:S,when:w}}},Q={matched:!1},X=/*#__PURE__*/function(){function n(n,t){void 0===t&&(t=Q),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],i=[e[0]],o=[];3===e.length&&"function"==typeof e[1]?(i.push(e[0]),o.push(e[1])):e.length>2&&i.push.apply(i,e.slice(1,e.length-1));var c={},f=Boolean(i.some(function(n){return a(n,t.input,function(n,t){c[n]=t})})&&o.every(function(n){return n(t.input)}))?{matched:!0,value:r(Object.keys(c).length?u in c?c[u]:c:this.input,this.input)}:{matched:!1};return new n(this.input,f)},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)}:{matched:!1})},t.otherwise=function(n){return this.state.matched?this.state.value:n(this.input,this.input)},t.exhaustive=function(){return this.run()},t.run=function(){if(this.state.matched)return this.state.value;var n;try{n=JSON.stringify(this.input)}catch(t){n=this.input}throw new Error("Pattern matching error: no pattern matches value "+n)},t.returnType=function(){return this},n}();n.P=L,n.Pattern=L,n.isMatching=l,n.match=function(n){return new X(n)}}); | ||
//# sourceMappingURL=index.umd.js.map |
@@ -7,7 +7,7 @@ /** | ||
import { SelectionType } from '../types/FindSelected.js'; | ||
import { Pattern, Matcher, MatcherType } from '../types/Pattern.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<unknown, unknown, MatcherType, SelectionType, unknown>; | ||
export declare const matchPattern: (pattern: Pattern<any>, value: any, select: (key: string, value: unknown) => void) => boolean; | ||
export declare const getSelectionKeys: (pattern: Pattern<any>) => string[]; | ||
export declare const flatMap: <a, b>(xs: a[], f: (v: a) => b[]) => b[]; | ||
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: <a, b>(xs: readonly a[], f: (v: a) => readonly b[]) => b[]; |
@@ -21,3 +21,9 @@ /** | ||
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 input: unique symbol; | ||
export type input = typeof input; | ||
export declare const override: unique symbol; | ||
export type override = typeof override; |
@@ -1,3 +0,2 @@ | ||
import { Pattern } from './types/Pattern.js'; | ||
import { MatchedValue } from './types/Match.js'; | ||
import { MatchedValue, Pattern } from './types/Pattern.js'; | ||
import * as P from './patterns.js'; | ||
@@ -19,3 +18,3 @@ /** | ||
*/ | ||
export declare function isMatching<p extends Pattern<any>>(pattern: p): (value: any) => value is MatchedValue<any, P.infer<p>>; | ||
export declare function isMatching<p extends Pattern<unknown>>(pattern: p): (value: any) => value is MatchedValue<any, P.infer<p>>; | ||
/** | ||
@@ -34,2 +33,2 @@ * `isMatching` takes pattern and a value and checks if the value matches this pattern. | ||
*/ | ||
export declare function isMatching<p extends Pattern<any>>(pattern: p, value: any): value is MatchedValue<any, P.infer<p>>; | ||
export declare function isMatching<p extends Pattern<unknown>>(pattern: p, value: any): value is MatchedValue<any, P.infer<p>>; |
@@ -21,3 +21,2 @@ import { Match } from './types/Match.js'; | ||
*/ | ||
export declare function match<input extends [any, ...any], output = symbols.unset>(value: input): Match<input, output>; | ||
export declare function match<input, output = symbols.unset>(value: input): Match<input, output>; | ||
export declare function match<const input, output = symbols.unset>(value: input): Match<input, output>; |
import * as symbols from './internals/symbols.js'; | ||
import { GuardFunction, Primitives } from './types/helpers.js'; | ||
import { matcher } from './internals/symbols.js'; | ||
import { ExtractPreciseValue } from './types/ExtractPreciseValue.js'; | ||
import { Fn, GuardFunction } from './types/helpers.js'; | ||
import { InvertPattern } from './types/InvertPattern.js'; | ||
import { Pattern, UnknownPattern, OptionalP, ArrayP, AndP, OrP, NotP, GuardP, SelectP, AnonymousSelectP, GuardExcludeP } from './types/Pattern.js'; | ||
export { Pattern }; | ||
import { Pattern, UnknownPattern, OptionalP, ArrayP, MapP, SetP, AndP, OrP, NotP, GuardP, SelectP, AnonymousSelectP, GuardExcludeP, CustomP, Matcher } from './types/Pattern.js'; | ||
export { 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<NarrowFn>` | ||
* key, which defines how this object should be matched by TS-Pattern. | ||
* | ||
* Note that this api is unstable. | ||
* | ||
* @example | ||
* ```ts | ||
* class Some<T> implements P.unstable_Matchable { | ||
* [P.matcher](): P.unstable_Matcher<Some<T>> | ||
* } | ||
* ``` | ||
*/ | ||
export type unstable_Matchable<narrowedOrFn, input = unknown, pattern = never> = CustomP<input, pattern, narrowedOrFn>; | ||
/** | ||
* @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<T> implements P.unstable_Matchable { | ||
* [P.matcher](): P.unstable_Matcher<Some<T>> | ||
* } | ||
* ``` | ||
*/ | ||
export type unstable_Matcher<narrowedOrFn, input = unknown, pattern = never> = ReturnType<CustomP<input, pattern, narrowedOrFn>[matcher]>; | ||
/** | ||
* `P.infer<typeof somePattern>` will return the type of the value | ||
@@ -16,3 +50,64 @@ * matched by this pattern. | ||
*/ | ||
export type infer<p extends Pattern<any>> = InvertPattern<p>; | ||
export type infer<p extends Pattern<any>> = InvertPattern<p, unknown>; | ||
export type narrow<i, p extends Pattern<any>> = ExtractPreciseValue<i, InvertPattern<p, i>>; | ||
type Chainable<p, omitted extends string = never> = p & Omit<{ | ||
/** | ||
* `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 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"Β }') | ||
*/ | ||
optional<input>(): Chainable<OptionalP<input, p>, omitted | 'optional'>; | ||
/** | ||
* `P.intersection(...patterns)` returns a pattern which matches | ||
* only if **every** patterns provided in parameter match the input. | ||
* | ||
* [Read 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' | ||
* ) | ||
*/ | ||
and<input, p2 extends Pattern<input>>(pattern: p2): Chainable<AndP<input, [p, p2]>, omitted>; | ||
/** | ||
* `P.union(...patterns)` returns a pattern which matches | ||
* if **at least one** of the patterns provided in parameter match the input. | ||
* | ||
* [Read documentation for `P.union` on GitHub](https://github.com/gvergnaud/ts-pattern#Punion-patterns) | ||
* | ||
* @example | ||
* match(value) | ||
* .with( | ||
* { type: P.union('a', 'b', 'c') }, | ||
* ({ user }) => 'will match { type: "a" | "b" | "c" }' | ||
* ) | ||
*/ | ||
or<input, p2 extends Pattern<input>>(pattern: p2): Chainable<OrP<input, [p, p2]>, omitted>; | ||
/** | ||
* `P.select()` is a pattern which will always match, | ||
* and will inject the selected piece of input in the handler function. | ||
* | ||
* [Read 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' | ||
* ) | ||
*/ | ||
select<input>(): Chainable<SelectP<symbols.anonymousSelectKey, input, p>, omitted | 'select' | 'or' | 'and'>; | ||
select<input, k extends string>(key: k): Chainable<SelectP<k, input, p>, omitted | 'select' | 'or' | 'and'>; | ||
}, omitted>; | ||
/** | ||
@@ -23,9 +118,13 @@ * `P.optional(subpattern)` takes a sub pattern and returns a pattern which matches if the | ||
* [Read documentation for `P.optional` on GitHub](https://github.com/gvergnaud/ts-pattern#Poptional-patterns) | ||
* @example | ||
* | ||
* @example | ||
* match(value) | ||
* .with({ greeting: P.optional('Hello') }, () => 'will match { greeting?: "Hello"Β }') | ||
*/ | ||
export declare function optional<input, p extends unknown extends input ? UnknownPattern : Pattern<input>>(pattern: p): OptionalP<input, p>; | ||
type Elem<xs> = xs extends readonly (infer x)[] ? x : never; | ||
export declare function optional<input, const p extends unknown extends input ? UnknownPattern : Pattern<input>>(pattern: p): Chainable<OptionalP<input, p>, 'optional'>; | ||
type UnwrapArray<xs> = xs extends readonly (infer x)[] ? x : never; | ||
type UnwrapSet<xs> = xs extends Set<infer x> ? x : never; | ||
type UnwrapMapKey<xs> = xs extends Map<infer k, any> ? k : never; | ||
type UnwrapMapValue<xs> = xs extends Map<any, infer v> ? v : never; | ||
type WithDefault<a, b> = [a] extends [never] ? b : a; | ||
/** | ||
@@ -41,4 +140,29 @@ * `P.array(subpattern)` takes a sub pattern and returns a pattern, which matches | ||
*/ | ||
export declare function array<input, p extends unknown extends input ? UnknownPattern : Pattern<Elem<input>>>(pattern: p): ArrayP<input, p>; | ||
export declare function array<input>(): Chainable<ArrayP<input, unknown> & Iterable<ArrayP<input, unknown>>>; | ||
export declare function array<input, const p extends Pattern<WithDefault<UnwrapArray<input>, unknown>>>(pattern: p): Chainable<ArrayP<input, p> & Iterable<ArrayP<input, p>>>; | ||
/** | ||
* `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<string>') | ||
*/ | ||
export declare function set<input>(): Chainable<SetP<input, unknown>>; | ||
export declare function set<input, const p extends Pattern<WithDefault<UnwrapSet<input>, unknown>>>(pattern: p): Chainable<SetP<input, p>>; | ||
/** | ||
* `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<string>') | ||
*/ | ||
export declare function map<input>(): Chainable<MapP<input, unknown, unknown>>; | ||
export declare function map<input, const pkey extends Pattern<WithDefault<UnwrapMapKey<input>, unknown>>, const pvalue extends Pattern<WithDefault<UnwrapMapValue<input>, unknown>>>(patternKey: pkey, patternValue: pvalue): Chainable<MapP<input, pkey, pvalue>>; | ||
/** | ||
* `P.intersection(...patterns)` returns a pattern which matches | ||
@@ -62,3 +186,3 @@ * only if **every** patterns provided in parameter match the input. | ||
*/ | ||
export declare function intersection<input, ps extends unknown extends input ? [UnknownPattern, ...UnknownPattern[]] : [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): AndP<input, ps>; | ||
export declare function intersection<input, const ps extends readonly [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): Chainable<AndP<input, ps>>; | ||
/** | ||
@@ -77,3 +201,3 @@ * `P.union(...patterns)` returns a pattern which matches | ||
*/ | ||
export declare function union<input, ps extends unknown extends input ? [UnknownPattern, ...UnknownPattern[]] : [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): OrP<input, ps>; | ||
export declare function union<input, const ps extends readonly [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): Chainable<OrP<input, ps>>; | ||
/** | ||
@@ -90,3 +214,3 @@ * `P.not(pattern)` returns a pattern which matches if the sub pattern | ||
*/ | ||
export declare function not<input, p extends Pattern<input> | Primitives>(pattern: p): NotP<input, p>; | ||
export declare function not<input, const p extends Pattern<input> | UnknownPattern>(pattern: p): Chainable<NotP<input, p>>; | ||
/** | ||
@@ -116,6 +240,13 @@ * `P.when((value) => boolean)` returns a pattern which matches | ||
*/ | ||
export declare function select(): AnonymousSelectP; | ||
export declare function select<input, patternOrKey extends string | (unknown extends input ? UnknownPattern : Pattern<input>)>(patternOrKey: patternOrKey): patternOrKey extends string ? SelectP<patternOrKey> : SelectP<symbols.anonymousSelectKey, input, patternOrKey>; | ||
export declare function select<input, p extends unknown extends input ? UnknownPattern : Pattern<input>, k extends string>(key: k, pattern: p): SelectP<k, input, p>; | ||
export declare function select(): Chainable<AnonymousSelectP, 'select' | 'or' | 'and'>; | ||
export declare function select<input, const patternOrKey extends string | (unknown extends input ? UnknownPattern : Pattern<input>)>(patternOrKey: patternOrKey): patternOrKey extends string ? Chainable<SelectP<patternOrKey, 'select' | 'or' | 'and'>> : Chainable<SelectP<symbols.anonymousSelectKey, input, patternOrKey>, 'select' | 'or' | 'and'>; | ||
export declare function select<input, const p extends unknown extends input ? UnknownPattern : Pattern<input>, const k extends string>(key: k, pattern: p): Chainable<SelectP<k, input, p>, 'select' | 'or' | 'and'>; | ||
type AnyConstructor = abstract new (...args: any[]) => any; | ||
type AnyPattern = Chainable<GuardP<unknown, unknown>, never>; | ||
type StringPattern = StringChainable<GuardP<unknown, string>, never>; | ||
type NumberPattern = NumberChainable<GuardP<unknown, number>, never>; | ||
type BooleanPattern = Chainable<GuardP<unknown, boolean>, never>; | ||
type BigIntPattern = BigIntChainable<GuardP<unknown, bigint>, never>; | ||
type SymbolPattern = Chainable<GuardP<unknown, symbol>, never>; | ||
type NullishPattern = Chainable<GuardP<unknown, null | undefined>, never>; | ||
/** | ||
@@ -130,3 +261,3 @@ * `P.any` is a wildcard pattern, matching **any value**. | ||
*/ | ||
export declare const any: GuardP<unknown, unknown>; | ||
export declare const any: AnyPattern; | ||
/** | ||
@@ -142,5 +273,48 @@ * `P._` is a wildcard pattern, matching **any value**. | ||
*/ | ||
export declare const _: GuardP<unknown, unknown>; | ||
export declare const _: AnyPattern; | ||
type MaybeAnd<omitted, input, p1, p2> = [omitted] extends [never] ? p2 : AndP<input, [p1, p2]>; | ||
type StringChainable<p extends Matcher<any, any, any, any, any>, omitted extends string = never> = Chainable<p, omitted> & Omit<{ | ||
/** | ||
* `P.string.startsWith(start)` is a pattern, matching **strings** starting with `start`. | ||
* | ||
* [Read 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<input, const start extends string>(start: start): StringChainable<MaybeAnd<omitted, input, p, GuardP<input, `${start}${string}`>>, omitted | 'startsWith'>; | ||
/** | ||
* `P.string.endsWith(end)` is a pattern, matching **strings** ending with `end`. | ||
* | ||
* [Read 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<input, const end extends string>(end: end): StringChainable<MaybeAnd<omitted, input, p, GuardP<input, `${string}${end}`>>, omitted | 'endsWith'>; | ||
/** | ||
* `P.string.includes(substr)` is a pattern, matching **strings** containing `substr`. | ||
* | ||
* [Read 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<input, const substr extends string>(substr: substr): StringChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, string, never>>, omitted>; | ||
/** | ||
* `P.string.regex(expr)` is a pattern, matching **strings** that `expr` regular expression. | ||
* | ||
* [Read documentation for `P.string.regex` on GitHub](https://github.com/gvergnaud/ts-pattern#Pstringregex) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.string.regex(/^https?:\/\//), () => 'url') | ||
*/ | ||
regex<input, const expr extends string | RegExp>(expr: expr): StringChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, string, never>>, omitted>; | ||
}, omitted>; | ||
/** | ||
* `P.string` is a wildcard pattern matching any **string**. | ||
* `P.string` is a wildcard pattern, matching any **string**. | ||
* | ||
@@ -153,6 +327,190 @@ * [Read documentation for `P.string` on GitHub](https://github.com/gvergnaud/ts-pattern#Pstring-wildcard) | ||
*/ | ||
export declare const string: GuardP<unknown, string>; | ||
export declare const string: StringPattern; | ||
/** | ||
* `P.number` is a wildcard pattern matching any **number**. | ||
* `P.number.between(min, max)` matches **number** between `min` and `max`, | ||
* equal to min or equal to max. | ||
* | ||
* [Read 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') | ||
*/ | ||
export declare const between: <input, const min extends number, const max extends number>(min: min, max: max) => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.lt(max)` matches **number** smaller than `max`. | ||
* | ||
* [Read documentation for `P.number.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberlt) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.lt(10), () => 'numbers < 10') | ||
*/ | ||
export declare const lt: <input, const max extends number>(max: max) => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.gt(min)` matches **number** greater than `min`. | ||
* | ||
* [Read documentation for `P.number.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumbergt) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.gt(10), () => 'numbers > 10') | ||
*/ | ||
export declare const gt: <input, const min extends number>(min: min) => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.lte(max)` matches **number** smaller than or equal to `max`. | ||
* | ||
* [Read documentation for `P.number.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberlte) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.lte(10), () => 'numbers <= 10') | ||
*/ | ||
export declare const lte: <input, const max extends number>(max: max) => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.gte(min)` matches **number** greater than or equal to `min`. | ||
* | ||
* [Read documentation for `P.number.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumbergte) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.gte(10), () => 'numbers >= 10') | ||
*/ | ||
export declare const gte: <input, const min extends number>(min: min) => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.int` matches **integer** numbers. | ||
* | ||
* [Read documentation for `P.number.int` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberint) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.int, () => 'an integer') | ||
*/ | ||
export declare const int: <input>() => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.finite` matches **finite numbers**. | ||
* | ||
* [Read documentation for `P.number.finite` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberfinite) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.finite, () => 'not Infinity') | ||
*/ | ||
export declare const finite: <input>() => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.positive` matches **positive** numbers. | ||
* | ||
* [Read documentation for `P.number.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberpositive) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.positive, () => 'number > 0') | ||
*/ | ||
export declare const positive: <input>() => GuardExcludeP<input, number, never>; | ||
/** | ||
* `P.number.negative` matches **negative** numbers. | ||
* | ||
* [Read documentation for `P.number.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumbernegative) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.negative, () => 'number < 0') | ||
*/ | ||
export declare const negative: <input>() => GuardExcludeP<input, number, never>; | ||
type NumberChainable<p, omitted extends string = never> = Chainable<p, omitted> & Omit<{ | ||
/** | ||
* `P.number.between(min, max)` matches **number** between `min` and `max`, | ||
* equal to min or equal to max. | ||
* | ||
* [Read 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<input, const min extends number, const max extends number>(min: min, max: max): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted>; | ||
/** | ||
* `P.number.lt(max)` matches **number** smaller than `max`. | ||
* | ||
* [Read 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<input, const max extends number>(max: max): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted>; | ||
/** | ||
* `P.number.gt(min)` matches **number** greater than `min`. | ||
* | ||
* [Read 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<input, const min extends number>(min: min): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted>; | ||
/** | ||
* `P.number.lte(max)` matches **number** smaller than or equal to `max`. | ||
* | ||
* [Read 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<input, const max extends number>(max: max): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted>; | ||
/** | ||
* `P.number.gte(min)` matches **number** greater than or equal to `min`. | ||
* | ||
* [Read 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<input, const min extends number>(min: min): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted>; | ||
/** | ||
* `P.number.int` matches **integer** numbers. | ||
* | ||
* [Read documentation for `P.number.int` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberint) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.int, () => 'an integer') | ||
*/ | ||
int<input>(): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted | 'int'>; | ||
/** | ||
* `P.number.finite` matches **finite numbers**. | ||
* | ||
* [Read documentation for `P.number.finite` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberfinite) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.finite, () => 'not Infinity') | ||
*/ | ||
finite<input>(): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted | 'finite'>; | ||
/** | ||
* `P.number.positive` matches **positive** numbers. | ||
* | ||
* [Read documentation for `P.number.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumberpositive) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.positive, () => 'number > 0') | ||
*/ | ||
positive<input>(): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted | 'positive' | 'negative'>; | ||
/** | ||
* `P.number.negative` matches **negative** numbers. | ||
* | ||
* [Read documentation for `P.number.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumbernegative) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.number.negative, () => 'number < 0') | ||
*/ | ||
negative<input>(): NumberChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, number, never>>, omitted | 'positive' | 'negative' | 'negative'>; | ||
}, omitted>; | ||
/** | ||
* `P.number` is a wildcard pattern, matching any **number**. | ||
* | ||
* [Read documentation for `P.number` on GitHub](https://github.com/gvergnaud/ts-pattern#Pnumber-wildcard) | ||
@@ -164,15 +522,150 @@ * | ||
*/ | ||
export declare const number: GuardP<unknown, number>; | ||
export declare const number: NumberPattern; | ||
/** | ||
* `P.boolean` is a wildcard pattern matching any **boolean**. | ||
* `P.bigint.between(min, max)` matches **bigint** between `min` and `max`, | ||
* equal to min or equal to max. | ||
* | ||
* [Read documentation for `P.boolean` on GitHub](https://github.com/gvergnaud/ts-pattern#boolean-wildcard) | ||
* [Read documentation for `P.bigint.between` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintbetween) | ||
* | ||
* @example | ||
* .with(P.boolean, () => 'will match on booleans') | ||
* match(value) | ||
* .with(P.bigint.between(0, 10), () => '0 <= numbers <= 10') | ||
*/ | ||
export declare const boolean: GuardP<unknown, boolean>; | ||
export declare const betweenBigInt: <input, const min extends bigint, const max extends bigint>(min: min, max: max) => GuardExcludeP<input, bigint, never>; | ||
/** | ||
* `P.bigint` is a wildcard pattern matching any **bigint**. | ||
* `P.bigint.lt(max)` matches **bigint** smaller than `max`. | ||
* | ||
* [Read documentation for `P.bigint.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#bigintlt) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.lt(10), () => 'numbers < 10') | ||
*/ | ||
export declare const ltBigInt: <input, const max extends bigint>(max: max) => GuardExcludeP<input, bigint, never>; | ||
/** | ||
* `P.bigint.gt(min)` matches **bigint** greater than `min`. | ||
* | ||
* [Read documentation for `P.bigint.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#bigintgt) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.gt(10), () => 'numbers > 10') | ||
*/ | ||
export declare const gtBigInt: <input, const min extends bigint>(min: min) => GuardExcludeP<input, bigint, never>; | ||
/** | ||
* `P.bigint.lte(max)` matches **bigint** smaller than or equal to `max`. | ||
* | ||
* [Read documentation for `P.bigint.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#bigintlte) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.lte(10), () => 'bigints <= 10') | ||
*/ | ||
export declare const lteBigInt: <input, const max extends bigint>(max: max) => GuardExcludeP<input, bigint, never>; | ||
/** | ||
* `P.bigint.gte(min)` matches **bigint** greater than or equal to `min`. | ||
* | ||
* [Read documentation for `P.bigint.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintgte) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.gte(10), () => 'bigints >= 10') | ||
*/ | ||
export declare const gteBigInt: <input, const min extends bigint>(min: min) => GuardExcludeP<input, bigint, never>; | ||
/** | ||
* `P.bigint.positive` matches **positive** bigints. | ||
* | ||
* [Read documentation for `P.bigint.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintpositive) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.positive, () => 'bigint > 0') | ||
*/ | ||
export declare const positiveBigInt: <input>() => GuardExcludeP<input, bigint, never>; | ||
/** | ||
* `P.bigint.negative` matches **negative** bigints. | ||
* | ||
* [Read documentation for `P.bigint.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintnegative) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.negative, () => 'bigint < 0') | ||
*/ | ||
export declare const negativeBigInt: <input>() => GuardExcludeP<input, bigint, never>; | ||
type BigIntChainable<p, omitted extends string = never> = Chainable<p, omitted> & Omit<{ | ||
/** | ||
* `P.bigint.between(min, max)` matches **bigint** between `min` and `max`, | ||
* equal to min or equal to max. | ||
* | ||
* [Read documentation for `P.bigint.between` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintbetween) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.between(0, 10), () => '0 <= numbers <= 10') | ||
*/ | ||
between<input, const min extends bigint, const max extends bigint>(min: min, max: max): BigIntChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, bigint, never>>, omitted>; | ||
/** | ||
* `P.bigint.lt(max)` matches **bigint** smaller than `max`. | ||
* | ||
* [Read documentation for `P.bigint.lt` on GitHub](https://github.com/gvergnaud/ts-pattern#bigintlt) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.lt(10), () => 'numbers < 10') | ||
*/ | ||
lt<input, const max extends bigint>(max: max): BigIntChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, bigint, never>>, omitted>; | ||
/** | ||
* `P.bigint.gt(min)` matches **bigint** greater than `min`. | ||
* | ||
* [Read documentation for `P.bigint.gt` on GitHub](https://github.com/gvergnaud/ts-pattern#bigintgt) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.gt(10), () => 'numbers > 10') | ||
*/ | ||
gt<input, const min extends bigint>(min: min): BigIntChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, bigint, never>>, omitted>; | ||
/** | ||
* `P.bigint.lte(max)` matches **bigint** smaller than or equal to `max`. | ||
* | ||
* [Read documentation for `P.bigint.lte` on GitHub](https://github.com/gvergnaud/ts-pattern#bigintlte) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.lte(10), () => 'bigints <= 10') | ||
*/ | ||
lte<input, const max extends bigint>(max: max): BigIntChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, bigint, never>>, omitted>; | ||
/** | ||
* `P.bigint.gte(min)` matches **bigint** greater than or equal to `min`. | ||
* | ||
* [Read documentation for `P.bigint.gte` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintgte) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.gte(10), () => 'bigints >= 10') | ||
*/ | ||
gte<input, const min extends bigint>(min: min): BigIntChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, bigint, never>>, omitted>; | ||
/** | ||
* `P.bigint.positive` matches **positive** bigints. | ||
* | ||
* [Read documentation for `P.bigint.positive` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintpositive) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.positive, () => 'bigint > 0') | ||
*/ | ||
positive<input>(): BigIntChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, bigint, never>>, omitted | 'positive' | 'negative'>; | ||
/** | ||
* `P.bigint.negative` matches **negative** bigints. | ||
* | ||
* [Read documentation for `P.bigint.negative` on GitHub](https://github.com/gvergnaud/ts-pattern#Pbigintnegative) | ||
* | ||
* @example | ||
* match(value) | ||
* .with(P.bigint.negative, () => 'bigint < 0') | ||
*/ | ||
negative<input>(): BigIntChainable<MaybeAnd<omitted, input, p, GuardExcludeP<input, bigint, never>>, omitted | 'positive' | 'negative' | 'negative'>; | ||
}, omitted>; | ||
/** | ||
* `P.bigint` is a wildcard pattern, matching any **bigint**. | ||
* | ||
* [Read documentation for `P.bigint` on GitHub](https://github.com/gvergnaud/ts-pattern#bigint-wildcard) | ||
@@ -183,6 +676,15 @@ * | ||
*/ | ||
export declare const bigint: GuardP<unknown, bigint>; | ||
export declare const bigint: BigIntPattern; | ||
/** | ||
* `P.symbol` is a wildcard pattern matching any **symbol**. | ||
* `P.boolean` is a wildcard pattern, matching any **boolean**. | ||
* | ||
* [Read 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 documentation for `P.symbol` on GitHub](https://github.com/gvergnaud/ts-pattern#symbol-wildcard) | ||
@@ -193,5 +695,5 @@ * | ||
*/ | ||
export declare const symbol: GuardP<unknown, symbol>; | ||
export declare const symbol: SymbolPattern; | ||
/** | ||
* `P.nullish` is a wildcard pattern matching **null** or **undefined**. | ||
* `P.nullish` is a wildcard pattern, matching **null** or **undefined**. | ||
* | ||
@@ -203,3 +705,3 @@ * [Read documentation for `P.nullish` on GitHub](https://github.com/gvergnaud/ts-pattern#nullish-wildcard) | ||
*/ | ||
export declare const nullish: GuardP<unknown, null | undefined>; | ||
export declare const nullish: NullishPattern; | ||
/** | ||
@@ -213,4 +715,19 @@ * `P.instanceOf(SomeClass)` is a pattern matching instances of a given class. | ||
*/ | ||
export declare function instanceOf<T extends AnyConstructor>(classConstructor: T): GuardP<unknown, InstanceType<T>>; | ||
export declare function instanceOf<T extends AnyConstructor>(classConstructor: T): Chainable<GuardP<unknown, InstanceType<T>>>; | ||
/** | ||
* `P.shape(somePattern)` allows for calling methods like `.optional()` or `.select()` | ||
* On structural patterns, like objects and arrays. | ||
* | ||
* [Read 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<input, p extends Pattern<input>>(pattern: p): Chainable<GuardP<input, InvertPattern<p, input>>>; | ||
/** | ||
* `P.typed<SomeType>()` is a way to set the input type this | ||
@@ -231,10 +748,10 @@ * pattern should match on. | ||
export declare function typed<input>(): { | ||
array<p extends Pattern<Elem<input>>>(pattern: p): ArrayP<input, p>; | ||
optional<p extends Pattern<input>>(pattern: p): OptionalP<input, p>; | ||
intersection<ps extends [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): AndP<input, ps>; | ||
union<ps extends [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): OrP<input, ps>; | ||
not<p extends Pattern<input>>(pattern: p): NotP<input, p>; | ||
when<narrowed extends input = never>(predicate: GuardFunction<input, narrowed>): GuardP<input, narrowed>; | ||
select<pattern extends Pattern<input>>(pattern: pattern): SelectP<symbols.anonymousSelectKey, input, pattern>; | ||
select<p extends Pattern<input>, k extends string>(key: k, pattern: p): SelectP<k, input, p>; | ||
array<const p extends Pattern<UnwrapArray<input>>>(pattern: p): Chainable<ArrayP<input, p>>; | ||
optional<const p extends Pattern<input>>(pattern: p): Chainable<OptionalP<input, p>>; | ||
intersection<const ps extends readonly [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): Chainable<AndP<input, ps>>; | ||
union<const ps extends readonly [Pattern<input>, ...Pattern<input>[]]>(...patterns: ps): Chainable<OrP<input, ps>>; | ||
not<const p extends Pattern<input>>(pattern: p): Chainable<NotP<input, p>>; | ||
when<const narrowed extends input = never>(predicate: GuardFunction<input, narrowed>): GuardP<input, narrowed>; | ||
select<const pattern extends Pattern<input>>(pattern: pattern): Chainable<SelectP<symbols.anonymousSelectKey, input, pattern>>; | ||
select<const p extends Pattern<input>, const k extends string>(key: k, pattern: p): Chainable<SelectP<k, input, p>>; | ||
}; |
@@ -1,4 +0,4 @@ | ||
import { Cast, Compute, Iterator, UpdateAt } from './helpers.js'; | ||
export type BuildMany<data, xs extends any[]> = xs extends any ? BuildOne<data, xs> : never; | ||
type BuildOne<data, xs extends any[]> = xs extends [ | ||
import { Compute, Iterator, UpdateAt } from './helpers.js'; | ||
export type BuildMany<data, xs extends readonly any[]> = xs extends any ? BuildOne<data, xs> : never; | ||
type BuildOne<data, xs extends readonly any[]> = xs extends [ | ||
[ | ||
@@ -9,10 +9,7 @@ infer value, | ||
...infer tail | ||
] ? BuildOne<Update<data, value, Cast<path, PropertyKey[]>>, tail> : data; | ||
] ? BuildOne<Update<data, value, Extract<path, readonly PropertyKey[]>>, tail> : data; | ||
type SafeGet<data, k extends PropertyKey, def> = k extends keyof data ? data[k] : def; | ||
type Update<data, value, path extends PropertyKey[]> = path extends [ | ||
infer head, | ||
...infer tail | ||
] ? data extends readonly [any, ...any] ? head extends number ? UpdateAt<data, Iterator<head>, Update<data[head], value, Cast<tail, PropertyKey[]>>> : never : data extends readonly (infer a)[] ? Update<a, value, Cast<tail, PropertyKey[]>>[] : data extends Set<infer a> ? Set<Update<a, value, Cast<tail, PropertyKey[]>>> : data extends Map<infer k, infer v> ? Map<k, Update<v, value, Cast<tail, PropertyKey[]>>> : Compute<Omit<data, Cast<head, PropertyKey>> & { | ||
[k in Cast<head, PropertyKey>]: Update<SafeGet<data, k, {}>, value, Cast<tail, PropertyKey[]>>; | ||
type Update<data, value, path extends readonly PropertyKey[]> = path extends readonly [infer head, ...infer tail] ? data extends readonly [any, ...any] ? head extends number ? UpdateAt<data, Iterator<head>, Update<data[head], value, Extract<tail, readonly PropertyKey[]>>> : never : data extends readonly (infer a)[] ? Update<a, value, Extract<tail, readonly PropertyKey[]>>[] : data extends Set<infer a> ? Set<Update<a, value, Extract<tail, readonly PropertyKey[]>>> : data extends Map<infer k, infer v> ? Map<k, Update<v, value, Extract<tail, readonly PropertyKey[]>>> : Compute<Omit<data, Extract<head, PropertyKey>> & { | ||
[k in Extract<head, PropertyKey>]: Update<SafeGet<data, k, {}>, value, Extract<tail, readonly PropertyKey[]>>; | ||
}> : value; | ||
export {}; |
import { BuildMany } from './BuildMany.js'; | ||
import type { IsAny, Cast, Values, Flatten, IsUnion, IsPlainObject, Length, UnionToTuple } from './helpers.js'; | ||
import type { IsAny, Values, Flatten, IsUnion, IsPlainObject, Length, UnionToTuple, IsReadonlyArray, ValueOf, MaybeAddReadonly, IsStrictArray } from './helpers.js'; | ||
import { IsMatching } from './IsMatching.js'; | ||
@@ -29,3 +29,3 @@ /** | ||
export type DistributeMatchingUnions<a, p> = IsAny<a> extends true ? any : BuildMany<a, Distribute<FindUnionsMany<a, p>>>; | ||
export type FindUnionsMany<a, p, path extends PropertyKey[] = []> = UnionToTuple<(p extends any ? IsMatching<a, p> extends true ? FindUnions<a, p, path> : [] : never) extends (infer T)[] ? T : never>; | ||
export type FindUnionsMany<a, p, path extends PropertyKey[] = []> = UnionToTuple<(p extends any ? IsMatching<a, p> extends true ? FindUnions<a, p, path> : [] : never) extends readonly (infer T)[] ? T : never>; | ||
/** | ||
@@ -84,6 +84,14 @@ * The reason we don't look further down the tree with lists, | ||
readonly [infer p1, infer p2] | ||
] ? [...FindUnions<a1, p1, [...path, 0]>, ...FindUnions<a2, p2, [...path, 1]>] : [a, p] extends [readonly [infer a1], readonly [infer p1]] ? FindUnions<a1, p1, [...path, 0]> : [] : a extends Set<any> ? [] : a extends Map<any, any> ? [] : [IsPlainObject<a>, IsPlainObject<p>] extends [true, true] ? Flatten<Values<{ | ||
] ? [...FindUnions<a1, p1, [...path, 0]>, ...FindUnions<a2, p2, [...path, 1]>] : [a, p] extends [readonly [infer a1], readonly [infer p1]] ? FindUnions<a1, p1, [...path, 0]> : p extends readonly [] | readonly [any, ...any] | readonly [...any, any] ? IsStrictArray<Extract<a, readonly any[]>> extends false ? [] : [ | ||
MaybeAddReadonly<(a extends readonly [any, ...any] | readonly [...any, any] ? never : []) | (p extends readonly [...any, any] ? [...Extract<a, readonly any[]>, ValueOf<a>] : [ValueOf<a>, ...Extract<a, readonly any[]>]), IsReadonlyArray<a>> extends infer aUnion ? { | ||
cases: aUnion extends any ? { | ||
value: aUnion; | ||
subUnions: []; | ||
} : never; | ||
path: path; | ||
} : never | ||
] : [] : a extends Set<any> ? [] : a extends Map<any, any> ? [] : [IsPlainObject<a>, IsPlainObject<p>] extends [true, true] ? Flatten<Values<{ | ||
[k in keyof a & keyof p]: FindUnions<a[k], p[k], [...path, k]>; | ||
}>> : []; | ||
export type Distribute<unions extends any[]> = unions extends [ | ||
export type Distribute<unions extends readonly any[]> = unions extends readonly [ | ||
{ | ||
@@ -102,4 +110,4 @@ cases: infer cases; | ||
], | ||
...Distribute<Cast<subUnions, any[]>>, | ||
...Distribute<Extract<subUnions, readonly any[]>>, | ||
...Distribute<tail> | ||
] : never : []; |
@@ -1,23 +0,4 @@ | ||
import type { ToExclude } from './Pattern.js'; | ||
import type { BuiltInObjects, Compute, ExcludeObjectIfContainsNever, IsAny, IsPlainObject, LeastUpperBound } from './helpers.js'; | ||
import { DeepExclude } from './DeepExclude.js'; | ||
export type ExtractPreciseValue<a, b> = unknown extends b ? a : IsAny<a> extends true ? b : b extends readonly [] ? [] : b extends ToExclude<infer b1> ? DeepExclude<a, b1> : b extends readonly (infer bItem)[] ? a extends readonly (infer aItem)[] ? b extends readonly [infer b1, infer b2, infer b3, infer b4, infer b5] ? a extends readonly [infer a1, infer a2, infer a3, infer a4, infer a5] ? ExcludeObjectIfContainsNever<[ | ||
ExtractPreciseValue<a1, b1>, | ||
ExtractPreciseValue<a2, b2>, | ||
ExtractPreciseValue<a3, b3>, | ||
ExtractPreciseValue<a4, b4>, | ||
ExtractPreciseValue<a5, b5> | ||
], '0' | '1' | '2' | '3' | '4'> : LeastUpperBound<a, b> : b extends readonly [infer b1, infer b2, infer b3, infer b4] ? a extends readonly [infer a1, infer a2, infer a3, infer a4] ? ExcludeObjectIfContainsNever<[ | ||
ExtractPreciseValue<a1, b1>, | ||
ExtractPreciseValue<a2, b2>, | ||
ExtractPreciseValue<a3, b3>, | ||
ExtractPreciseValue<a4, b4> | ||
], '0' | '1' | '2' | '3'> : LeastUpperBound<a, b> : b extends readonly [infer b1, infer b2, infer b3] ? a extends readonly [infer a1, infer a2, infer a3] ? ExcludeObjectIfContainsNever<[ | ||
ExtractPreciseValue<a1, b1>, | ||
ExtractPreciseValue<a2, b2>, | ||
ExtractPreciseValue<a3, b3> | ||
], '0' | '1' | '2'> : LeastUpperBound<a, b> : b extends readonly [infer b1, infer b2] ? a extends readonly [infer a1, infer a2] ? ExcludeObjectIfContainsNever<[ | ||
ExtractPreciseValue<a1, b1>, | ||
ExtractPreciseValue<a2, b2> | ||
], '0' | '1'> : LeastUpperBound<a, b> : b extends readonly [infer b1] ? a extends readonly [infer a1] ? ExcludeObjectIfContainsNever<[ExtractPreciseValue<a1, b1>], '0'> : LeastUpperBound<a, b> : ExtractPreciseValue<aItem, bItem> extends infer preciseValue ? [preciseValue] extends [never] ? never : preciseValue[] : never : LeastUpperBound<a, b> : b extends Map<infer bk, infer bv> ? a extends Map<infer ak, infer av> ? Map<ExtractPreciseValue<ak, bk>, ExtractPreciseValue<av, bv>> : LeastUpperBound<a, b> : b extends Set<infer bv> ? a extends Set<infer av> ? Set<ExtractPreciseValue<av, bv>> : LeastUpperBound<a, b> : IsPlainObject<b, BuiltInObjects | Error> extends true ? a extends object ? a extends b ? a : b extends a ? [Exclude<keyof a, keyof b>] extends [never] ? b : Compute<b & Omit<a, keyof b>> : [keyof a & keyof b] extends [never] ? never : ExcludeObjectIfContainsNever<Compute<{ | ||
import type { Override } from './Pattern.js'; | ||
import type { BuiltInObjects, Compute, ExcludeObjectIfContainsNever, IsPlainObject, IsReadonlyArray, LeastUpperBound, MaybeAddReadonly, ValueOf } from './helpers.js'; | ||
export type ExtractPreciseValue<a, b> = b extends Override<infer b1> ? b1 : unknown extends b ? a : 0 extends 1 & b ? a : 0 extends 1 & a ? b : b extends readonly [] ? [] : b extends readonly any[] ? ExtractPreciseArrayValue<a, b, IsReadonlyArray<a>> : b extends Map<infer bk, infer bv> ? a extends Map<infer ak, infer av> ? Map<ExtractPreciseValue<ak, bk>, ExtractPreciseValue<av, bv>> : LeastUpperBound<a, b> : b extends Set<infer bv> ? a extends Set<infer av> ? Set<ExtractPreciseValue<av, bv>> : LeastUpperBound<a, b> : IsPlainObject<b, BuiltInObjects | Error> extends true ? a extends object ? a extends b ? a : b extends a ? [Exclude<keyof a, keyof b>] extends [never] ? b : ExcludeObjectIfContainsNever<Compute<b & Omit<a, keyof b>>> : [keyof a & keyof b] extends [never] ? never : ExcludeObjectIfContainsNever<Compute<{ | ||
[k in Exclude<keyof a, keyof b>]: a[k]; | ||
@@ -27,1 +8,19 @@ } & { | ||
}>, keyof b & string> : LeastUpperBound<a, b> : LeastUpperBound<a, b>; | ||
type ExtractPreciseArrayValue<a, b, isReadonly extends boolean, startOutput extends any[] = [], endOutput extends any[] = []> = 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<a1, b1> extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue<aRest, bRest, isReadonly, [ | ||
...startOutput, | ||
currentValue | ||
], endOutput> : never : ExtractPreciseValue<aItem, b1> extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue<aItem[], bRest, isReadonly, [ | ||
...startOutput, | ||
currentValue | ||
], endOutput> : never : b extends readonly [...infer bInit, infer b1] ? a extends readonly [...infer aInit, infer a1] ? ExtractPreciseValue<a1, b1> extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue<aInit, bInit, isReadonly, startOutput, [ | ||
...endOutput, | ||
currentValue | ||
]> : never : ExtractPreciseValue<aItem, b1> extends infer currentValue ? [currentValue] extends [never] ? never : ExtractPreciseArrayValue<aItem[], bInit, isReadonly, startOutput, [ | ||
...endOutput, | ||
currentValue | ||
]> : never : ExtractPreciseValue<ValueOf<b>, aItem> extends infer currentValue ? [currentValue] extends [never] ? never : MaybeAddReadonly<[ | ||
...startOutput, | ||
...currentValue[], | ||
...endOutput | ||
], isReadonly> : never : LeastUpperBound<a, b>; | ||
export {}; |
import type * as symbols from '../internals/symbols.js'; | ||
import type { Cast, Equal, IsAny, TupleKeys, UnionToTuple } from './helpers.js'; | ||
import type { Matcher, Pattern } from './Pattern.js'; | ||
import type { AnyMatcher, Matcher, Pattern } from './Pattern.js'; | ||
import type { Equal, Primitives, ValueOf, UnionToTuple } from './helpers.js'; | ||
type SelectionsRecord = Record<string, [unknown, unknown[]]>; | ||
@@ -19,11 +19,29 @@ export type None = { | ||
}; | ||
type ReduceFindSelectionUnion<i, ps extends any[], output = never> = ps extends [infer head, ...infer tail] ? ReduceFindSelectionUnion<i, tail, output | FindSelectionUnion<i, head>> : output; | ||
export type FindSelectionUnion<i, p, path extends any[] = []> = IsAny<i> extends true ? never : p extends Matcher<any, infer pattern, infer matcherType, infer sel> ? { | ||
type ReduceFindSelectionUnion<i, ps extends readonly any[], output = never> = ps extends readonly [infer head, ...infer tail] ? ReduceFindSelectionUnion<i, tail, output | FindSelectionUnion<i, head>> : output; | ||
type FindSelectionUnionInArray<i, p, path extends any[] = [], output = never> = i extends readonly (infer ii)[] ? p extends readonly [] ? output : p extends readonly [infer p1, ...infer pRest] ? i extends readonly [infer i1, ...infer iRest] ? FindSelectionUnionInArray<iRest, pRest, [ | ||
...path, | ||
p['length'] | ||
], output | FindSelectionUnion<i1, p1, [...path, p['length']]>> : FindSelectionUnionInArray<ii[], pRest, [ | ||
...path, | ||
p['length'] | ||
], output | FindSelectionUnion<ii, p1, [...path, p['length']]>> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? FindSelectionUnionInArray<iInit, pInit, [ | ||
...path, | ||
p['length'] | ||
], output | FindSelectionUnion<i1, p1, [...path, p['length']]>> : FindSelectionUnionInArray<ii[], pInit, [ | ||
...path, | ||
p['length'] | ||
], output | FindSelectionUnion<ii, p1, [...path, p['length']]>> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? output | FindSelectionUnion<i, pRest, [...path, p['length']]> : output | FindSelectionUnion<ii, ValueOf<p>, [ | ||
...path, | ||
Extract<p, readonly any[]>['length'] | ||
]> : output; | ||
export type FindSelectionUnion<i, p, path extends any[] = []> = 0 extends 1 & i ? never : 0 extends 1 & p ? never : p extends Primitives ? never : p extends Matcher<any, infer pattern, infer matcherType, infer sel> ? { | ||
select: sel extends Some<infer k> ? { | ||
[kk in k]: [i, path]; | ||
} | FindSelectionUnion<i, pattern, path> : never; | ||
array: i extends (infer ii)[] ? MapList<FindSelectionUnion<ii, pattern>> : never; | ||
array: i extends readonly (infer ii)[] ? MapList<FindSelectionUnion<ii, pattern>> : never; | ||
map: never; | ||
set: never; | ||
optional: MapOptional<FindSelectionUnion<i, pattern>>; | ||
or: MapOptional<ReduceFindSelectionUnion<i, Cast<pattern, any[]>>>; | ||
and: ReduceFindSelectionUnion<i, Cast<pattern, any[]>>; | ||
or: MapOptional<ReduceFindSelectionUnion<i, Extract<pattern, readonly any[]>>>; | ||
and: ReduceFindSelectionUnion<i, Extract<pattern, readonly any[]>>; | ||
not: never; | ||
@@ -33,8 +51,4 @@ default: sel extends Some<infer k> ? { | ||
} : never; | ||
}[matcherType] : p extends readonly (infer pp)[] ? i extends readonly (infer ii)[] ? p extends readonly [any, ...any[]] ? i extends readonly [any, ...any[]] ? { | ||
[k in TupleKeys & keyof i & keyof p]: FindSelectionUnion<i[k], p[k], [ | ||
...path, | ||
k | ||
]>; | ||
}[TupleKeys & keyof i & keyof p] : FindSelectionUnion<ii, p[number], [...path, 0]> : FindSelectionUnion<ii, pp, [...path, 0]> : never : p extends object ? i extends object ? { | ||
custom: never; | ||
}[matcherType] : p extends readonly any[] ? FindSelectionUnionInArray<i, p> : p extends {} ? i extends {} ? { | ||
[k in keyof p]: k extends keyof i ? FindSelectionUnion<i[k], p[k], [...path, k]> : never; | ||
@@ -60,5 +74,5 @@ }[keyof p] : never : never; | ||
}; | ||
type ReduceToRecord<selections extends any[], output extends SelectionsRecord = {}> = selections extends [infer sel, ...infer rest] ? ReduceToRecord<rest, ConcatSelections<Cast<sel, SelectionsRecord>, output>> : output; | ||
type ReduceToRecord<selections extends any[], output extends SelectionsRecord = {}> = selections extends [infer sel, ...infer rest] ? ReduceToRecord<rest, ConcatSelections<Extract<sel, SelectionsRecord>, output>> : output; | ||
export type Selections<i, p> = FindSelectionUnion<i, p> extends infer u ? [u] extends [never] ? i : SelectionToArgs<ReduceToRecord<UnionToTuple<u>>> : i; | ||
export type FindSelected<i, p> = Equal<p, Pattern<i>> extends true ? i : Selections<i, p>; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
export type ValueOf<a> = a extends any[] ? a[number] : a[keyof a]; | ||
export type ValueOf<a> = a extends readonly any[] ? a[number] : a[keyof a]; | ||
export type Values<a extends object> = UnionToTuple<ValueOf<a>>; | ||
@@ -16,3 +16,3 @@ /** | ||
**/ | ||
export type ExcludeIfContainsNever<a, b> = b extends Map<any, any> | Set<any> ? a : b extends readonly [any, ...any] ? ExcludeObjectIfContainsNever<a, keyof b & ('0' | '1' | '2' | '3' | '4')> : b extends any[] ? ExcludeObjectIfContainsNever<a, keyof b & number> : ExcludeObjectIfContainsNever<a, keyof b & string>; | ||
export type ExcludeIfContainsNever<a, b> = b extends Map<any, any> | Set<any> ? a : b extends readonly [any, ...any] ? ExcludeObjectIfContainsNever<a, keyof b & ('0' | '1' | '2' | '3' | '4')> : b extends readonly any[] ? ExcludeObjectIfContainsNever<a, keyof b & number> : ExcludeObjectIfContainsNever<a, keyof b & string>; | ||
export type ExcludeObjectIfContainsNever<a, keyConstraint = unknown> = a extends any ? 'exclude' extends { | ||
@@ -24,4 +24,3 @@ [k in keyConstraint & keyof a]-?: [a[k]] extends [never] ? 'exclude' : 'include'; | ||
export type UnionToTuple<union, output extends any[] = []> = UnionToIntersection<union extends any ? (t: union) => union : never> extends (_: any) => infer elem ? UnionToTuple<Exclude<union, elem>, [elem, ...output]> : output; | ||
export type Cast<a, b> = a extends b ? a : never; | ||
export type Flatten<xs extends any[], output extends any[] = []> = xs extends readonly [infer head, ...infer tail] ? Flatten<tail, [...output, ...Cast<head, any[]>]> : output; | ||
export type Flatten<xs extends readonly any[], output extends any[] = []> = xs extends readonly [infer head, ...infer tail] ? Flatten<tail, [...output, ...Extract<head, readonly any[]>]> : output; | ||
export type Equal<a, b> = (<T>() => T extends a ? 1 : 2) extends <T>() => T extends b ? 1 : 2 ? true : false; | ||
@@ -46,9 +45,10 @@ export type Expect<a extends true> = a; | ||
export type IntersectObjects<a> = (a extends any ? keyof a : never) extends infer allKeys ? { | ||
[k in Cast<allKeys, PropertyKey>]: a extends any ? k extends keyof a ? a[k] : never : never; | ||
[k in Extract<allKeys, PropertyKey>]: a extends any ? k extends keyof a ? a[k] : never : never; | ||
} : never; | ||
export type WithDefault<a, def> = [a] extends [never] ? def : a; | ||
export type ExtractWithDefault<a, b, def> = a extends b ? a : def; | ||
export type IsLiteral<a> = [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<Primitives, undefined | null>; | ||
export type TupleKeys = 0 | 1 | 2 | 3 | 4; | ||
export type TupleKeys = '0' | '1' | '2' | '3' | '4'; | ||
export type Union<a, b> = [b] extends [a] ? a : [a] extends [b] ? b : a | b; | ||
@@ -59,3 +59,3 @@ /** | ||
export type GuardValue<fn> = fn extends (value: any) => value is infer b ? b : fn extends (value: infer a) => unknown ? a : never; | ||
export type GuardFunction<input, narrowed> = ((value: input) => value is Cast<narrowed, input>) | ((value: input) => boolean); | ||
export type GuardFunction<input, narrowed> = ((value: input) => value is Extract<narrowed, input>) | ((value: input) => boolean); | ||
export type Some<bools extends boolean[]> = true extends bools[number] ? true : false; | ||
@@ -65,1 +65,24 @@ export type All<bools extends boolean[]> = bools[number] extends true ? true : false; | ||
export type Not<a extends boolean> = a extends true ? false : true; | ||
type AllKeys<a> = a extends any ? keyof a : never; | ||
export type MergeUnion<a> = { | ||
readonly [k in AllKeys<a>]: a extends any ? k extends keyof a ? a[k] : never : never; | ||
}; | ||
export type IsFixedSizeTuple<a extends readonly any[]> = IsLiteral<Length<a>>; | ||
export type IsTuple<a extends readonly any[]> = a extends readonly [] | readonly [any, ...any] | readonly [...any, any] ? true : false; | ||
export type IsStrictArray<a extends readonly any[]> = Not<IsTuple<a>>; | ||
export type IsReadonlyArray<a> = a extends readonly any[] ? a extends any[] ? false : true : false; | ||
export type MaybeAddReadonly<a, shouldAdd extends boolean> = shouldAdd extends true ? Readonly<a> : a; | ||
export type MapKey<T> = T extends Map<infer K, any> ? K : never; | ||
export type MapValue<T> = T extends Map<any, infer V> ? V : never; | ||
export type SetValue<T> = T extends Set<infer V> ? V : never; | ||
export type ReadonlyArrayValue<T> = T extends ReadonlyArray<infer V> ? V : never; | ||
export type ExtractPlainObject<T> = T extends any ? IsPlainObject<T> extends true ? T : never : never; | ||
export type GetKey<O, K> = O extends any ? K extends keyof O ? O[K] : never : never; | ||
export interface Fn { | ||
input: unknown; | ||
output: unknown; | ||
} | ||
export type Call<fn extends Fn, input> = (fn & { | ||
input: input; | ||
})['output']; | ||
export {}; |
import { DeepExclude } from './DeepExclude.js'; | ||
import { IsPlainObject, Primitives, IsLiteral, ValueOf, Compute, Cast, Equal, Extends, Not, All, NonLiteralPrimitive } from './helpers.js'; | ||
import type { Matcher, Pattern, ToExclude } from './Pattern.js'; | ||
import { IsPlainObject, Primitives, IsLiteral, ValueOf, Compute, Equal, Extends, Not, All, NonLiteralPrimitive, MaybeAddReadonly, IsReadonlyArray, MapKey, MapValue, SetValue, ExtractPlainObject, GetKey, Call, Fn, ReadonlyArrayValue, ExtractWithDefault } from './helpers.js'; | ||
import type { Matcher, Pattern, Override, AnyMatcher } from './Pattern.js'; | ||
type OptionalKeys<p> = ValueOf<{ | ||
[k in keyof p]: p[k] extends Matcher<any, any, infer matcherType> ? matcherType extends 'optional' ? k : never : never; | ||
[k in keyof p]: 0 extends 1 & p[k] ? never : p[k] extends Matcher<any, any, infer matcherType> ? matcherType extends 'optional' ? k : never : never; | ||
}>; | ||
type ReduceUnion<tuple extends any[], output = never> = tuple extends readonly [ | ||
infer p, | ||
...infer tail | ||
] ? ReduceUnion<tail, output | InvertPattern<p>> : output; | ||
type ReduceIntersection<tuple extends any[], output = unknown> = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersection<tail, output & InvertPattern<p>> : output; | ||
type ReduceUnion<tuple extends readonly any[], i, output = never> = tuple extends readonly [infer p, ...infer tail] ? ReduceUnion<tail, i, output | InvertPatternInternal<p, i>> : output; | ||
type ReduceIntersection<tuple extends readonly any[], i, output = unknown> = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersection<tail, i, output & InvertPatternInternal<p, i>> : output; | ||
type InvertArrayPattern<p, i, startOutput extends any[] = [], endOutput extends any[] = []> = 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<pRest, iRest, [ | ||
...startOutput, | ||
InvertPatternInternal<p1, i1> | ||
], endOutput> : InvertArrayPattern<pRest, ii[], [ | ||
...startOutput, | ||
InvertPatternInternal<p1, ii> | ||
], endOutput> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? InvertArrayPattern<pInit, iInit, startOutput, [ | ||
...endOutput, | ||
InvertPatternInternal<p1, i1> | ||
]> : InvertArrayPattern<pInit, ii[], startOutput, [ | ||
...endOutput, | ||
InvertPatternInternal<p1, ii> | ||
]> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? [ | ||
...startOutput, | ||
...Extract<InvertPatternInternal<pRest, i>, readonly any[]>, | ||
...endOutput | ||
] : [...startOutput, ...InvertPatternInternal<ValueOf<p>, ii>[], ...endOutput] : never; | ||
/** | ||
* ### InvertPattern | ||
* ### 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<p> = p extends Matcher<infer input, infer narrowed, infer matcherType, any> ? { | ||
not: ToExclude<InvertPattern<narrowed>>; | ||
select: InvertPattern<narrowed>; | ||
array: InvertPattern<narrowed>[]; | ||
optional: InvertPattern<narrowed> | undefined; | ||
and: ReduceIntersection<Cast<narrowed, any[]>>; | ||
or: ReduceUnion<Cast<narrowed, any[]>>; | ||
default: [narrowed] extends [never] ? input : narrowed; | ||
}[matcherType] : p extends Primitives ? p : p extends readonly (infer pp)[] ? p extends readonly [infer p1, infer p2, infer p3, infer p4, infer p5] ? [ | ||
InvertPattern<p1>, | ||
InvertPattern<p2>, | ||
InvertPattern<p3>, | ||
InvertPattern<p4>, | ||
InvertPattern<p5> | ||
] : p extends readonly [infer p1, infer p2, infer p3, infer p4] ? [ | ||
InvertPattern<p1>, | ||
InvertPattern<p2>, | ||
InvertPattern<p3>, | ||
InvertPattern<p4> | ||
] : p extends readonly [infer p1, infer p2, infer p3] ? [InvertPattern<p1>, InvertPattern<p2>, InvertPattern<p3>] : p extends readonly [infer p1, infer p2] ? [InvertPattern<p1>, InvertPattern<p2>] : p extends readonly [infer p1] ? [InvertPattern<p1>] : p extends readonly [] ? [] : InvertPattern<pp>[] : p extends Map<infer pk, infer pv> ? Map<pk, InvertPattern<pv>> : p extends Set<infer pv> ? Set<InvertPattern<pv>> : IsPlainObject<p> extends true ? OptionalKeys<p> extends infer optKeys ? [optKeys] extends [never] ? { | ||
[k in Exclude<keyof p, optKeys>]: InvertPattern<p[k]>; | ||
export type InvertPattern<p, input> = Equal<Pattern<input>, p> extends true ? never : InvertPatternInternal<p, input>; | ||
type InvertPatternInternal<p, input> = 0 extends 1 & p ? never : p extends Matcher<infer _input, infer subpattern, infer matcherType, any, infer narrowedOrFn> ? { | ||
not: DeepExclude<input, InvertPatternInternal<subpattern, input>>; | ||
select: InvertPatternInternal<subpattern, input>; | ||
array: InvertPatternInternal<subpattern, ReadonlyArrayValue<input>>[]; | ||
map: subpattern extends [infer pk, infer pv] ? Map<InvertPatternInternal<pk, MapKey<Extract<input, Map<any, any>>>>, InvertPatternInternal<pv, MapValue<Extract<input, Map<any, any>>>>> : never; | ||
set: Set<InvertPatternInternal<subpattern, SetValue<Extract<input, Set<any>>>>>; | ||
optional: InvertPatternInternal<subpattern, Exclude<input, undefined>> | undefined; | ||
and: ReduceIntersection<Extract<subpattern, readonly any[]>, input>; | ||
or: ReduceUnion<Extract<subpattern, readonly any[]>, input>; | ||
default: [subpattern] extends [never] ? input : subpattern; | ||
custom: Override<narrowedOrFn extends Fn ? Call<narrowedOrFn, input> : narrowedOrFn>; | ||
}[matcherType] : p extends Primitives ? p : p extends readonly any[] ? InvertArrayPattern<p, ExtractWithDefault<input, readonly any[], unknown[]>> : IsPlainObject<p> extends true ? OptionalKeys<p> extends infer optKeys ? [optKeys] extends [never] ? { | ||
[k in Exclude<keyof p, optKeys>]: InvertPatternInternal<p[k], GetKey<ExtractPlainObject<input>, k>>; | ||
} : Compute<{ | ||
[k in Exclude<keyof p, optKeys>]: InvertPattern<p[k]>; | ||
[k in Exclude<keyof p, optKeys>]: InvertPatternInternal<p[k], GetKey<ExtractPlainObject<input>, k>>; | ||
} & { | ||
[k in Cast<optKeys, keyof p>]?: InvertPattern<p[k]>; | ||
[k in Extract<optKeys, keyof p>]?: InvertPatternInternal<p[k], GetKey<ExtractPlainObject<input>, k>>; | ||
}> : never : p; | ||
export type ReduceIntersectionForExclude<tuple extends any[], i, output = unknown> = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersectionForExclude<tail, i, output & InvertPatternForExcludeInternal<p, i, unknown>> : output; | ||
export type ReduceUnionForExclude<tuple extends any[], i, output = never> = tuple extends readonly [infer p, ...infer tail] ? ReduceUnionForExclude<tail, i, output | InvertPatternForExcludeInternal<p, i, never>> : output; | ||
export type ReduceIntersectionForExclude<tuple extends readonly any[], i, output = unknown> = tuple extends readonly [infer p, ...infer tail] ? ReduceIntersectionForExclude<tail, i, output & InvertPatternForExcludeInternal<p, i, unknown>> : output; | ||
export type ReduceUnionForExclude<tuple extends readonly any[], i, output = never> = tuple extends readonly [infer p, ...infer tail] ? ReduceUnionForExclude<tail, i, output | InvertPatternForExcludeInternal<p, i, never>> : output; | ||
type ExcludeIfExists<a, b> = [ | ||
@@ -52,41 +59,45 @@ b | ||
]> extends true ? never : DeepExclude<a, b>; | ||
type InvertArrayPatternForExclude<p, i, empty, isReadonly extends boolean, startOutput extends any[] = [], endOutput extends any[] = []> = 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<pRest, iRest, empty, isReadonly, [ | ||
...startOutput, | ||
InvertPatternForExcludeInternal<p1, i1, empty> | ||
], endOutput> : InvertArrayPatternForExclude<pRest, ii[], empty, isReadonly, [ | ||
...startOutput, | ||
InvertPatternForExcludeInternal<p1, ii, empty> | ||
], endOutput> : p extends readonly [...infer pInit, infer p1] ? i extends readonly [...infer iInit, infer i1] ? InvertArrayPatternForExclude<pInit, iInit, empty, isReadonly, startOutput, [ | ||
...endOutput, | ||
InvertPatternForExcludeInternal<p1, i1, empty> | ||
]> : InvertArrayPatternForExclude<pInit, ii[], empty, isReadonly, startOutput, [ | ||
...endOutput, | ||
InvertPatternForExcludeInternal<p1, ii, empty> | ||
]> : p extends readonly [...(readonly (infer pRest & AnyMatcher)[])] ? MaybeAddReadonly<[ | ||
...startOutput, | ||
...Extract<InvertPatternForExcludeInternal<pRest, i, empty>, readonly any[]>, | ||
...endOutput | ||
], isReadonly> : MaybeAddReadonly<[ | ||
...startOutput, | ||
...InvertPatternForExcludeInternal<ValueOf<p>, ii, empty>[], | ||
...endOutput | ||
], isReadonly> : empty; | ||
/** | ||
* ### InvertPatternForExclude | ||
*/ | ||
export type InvertPatternForExclude<p, i> = Equal<p, Pattern<i>> extends true ? never : InvertPatternForExcludeInternal<p, i>; | ||
type InvertPatternForExcludeInternal<p, i, empty = never> = [ | ||
p | ||
] extends [Primitives] ? IsLiteral<p> extends true ? p : IsLiteral<i> extends true ? p : empty : p extends Matcher<infer matchableInput, infer subpattern, infer matcherType, any, infer excluded> ? { | ||
export type InvertPatternForExclude<p, i> = Equal<Pattern<i>, p> extends true ? never : InvertPatternForExcludeInternal<p, i>; | ||
type InvertPatternForExcludeInternal<p, i, empty = never> = unknown extends p ? i : [p] extends [Primitives] ? IsLiteral<p> extends true ? p : IsLiteral<i> extends true ? p : empty : p extends Matcher<infer matchableInput, infer subpattern, infer matcherType, any, infer excluded> ? { | ||
select: InvertPatternForExcludeInternal<subpattern, i, empty>; | ||
array: i extends readonly (infer ii)[] ? InvertPatternForExcludeInternal<subpattern, ii, empty>[] : empty; | ||
map: subpattern extends [infer pk, infer pv] ? i extends Map<infer ik, infer iv> ? Map<InvertPatternForExcludeInternal<pk, ik, empty>, InvertPatternForExcludeInternal<pv, iv, empty>> : empty : empty; | ||
set: i extends Set<infer iv> ? Set<InvertPatternForExcludeInternal<subpattern, iv, empty>> : empty; | ||
optional: InvertPatternForExcludeInternal<subpattern, i, empty> | undefined; | ||
and: ReduceIntersectionForExclude<Cast<subpattern, any[]>, i>; | ||
or: ReduceUnionForExclude<Cast<subpattern, any[]>, i>; | ||
and: ReduceIntersectionForExclude<Extract<subpattern, readonly any[]>, i>; | ||
or: ReduceUnionForExclude<Extract<subpattern, readonly any[]>, i>; | ||
not: ExcludeIfExists<unknown extends matchableInput ? i : matchableInput, InvertPatternForExcludeInternal<subpattern, i>>; | ||
default: excluded; | ||
}[matcherType] : p extends readonly (infer pp)[] ? i extends readonly (infer ii)[] ? p extends readonly [infer p1, infer p2, infer p3, infer p4, infer p5] ? i extends readonly [infer i1, infer i2, infer i3, infer i4, infer i5] ? readonly [ | ||
InvertPatternForExcludeInternal<p1, i1, empty>, | ||
InvertPatternForExcludeInternal<p2, i2, empty>, | ||
InvertPatternForExcludeInternal<p3, i3, empty>, | ||
InvertPatternForExcludeInternal<p4, i4, empty>, | ||
InvertPatternForExcludeInternal<p5, i5, empty> | ||
] : empty : p extends readonly [infer p1, infer p2, infer p3, infer p4] ? i extends readonly [infer i1, infer i2, infer i3, infer i4] ? readonly [ | ||
InvertPatternForExcludeInternal<p1, i1, empty>, | ||
InvertPatternForExcludeInternal<p2, i2, empty>, | ||
InvertPatternForExcludeInternal<p3, i3, empty>, | ||
InvertPatternForExcludeInternal<p4, i4, empty> | ||
] : empty : p extends readonly [infer p1, infer p2, infer p3] ? i extends readonly [infer i1, infer i2, infer i3] ? readonly [ | ||
InvertPatternForExcludeInternal<p1, i1, empty>, | ||
InvertPatternForExcludeInternal<p2, i2, empty>, | ||
InvertPatternForExcludeInternal<p3, i3, empty> | ||
] : empty : p extends readonly [infer p1, infer p2] ? i extends readonly [infer i1, infer i2] ? readonly [ | ||
InvertPatternForExcludeInternal<p1, i1, empty>, | ||
InvertPatternForExcludeInternal<p2, i2, empty> | ||
] : empty : p extends readonly [infer p1] ? i extends readonly [infer i1] ? readonly [InvertPatternForExcludeInternal<p1, i1, empty>] : empty : p extends readonly [] ? [] : InvertPatternForExcludeInternal<pp, ii, empty>[] : empty : p extends Map<infer pk, infer pv> ? i extends Map<any, infer iv> ? Map<pk, InvertPatternForExcludeInternal<pv, iv, empty>> : empty : p extends Set<infer pv> ? i extends Set<infer iv> ? Set<InvertPatternForExcludeInternal<pv, iv, empty>> : empty : IsPlainObject<p> extends true ? i extends object ? [keyof p & keyof i] extends [never] ? empty : OptionalKeys<p> extends infer optKeys ? [optKeys] extends [never] ? { | ||
readonly [k in keyof p]: k extends keyof i ? InvertPatternForExcludeInternal<p[k], i[k], empty> : InvertPattern<p[k]>; | ||
custom: excluded extends infer narrowedOrFn extends Fn ? Call<narrowedOrFn, i> : excluded; | ||
}[matcherType] : p extends readonly any[] ? Extract<i, readonly any[]> extends infer arrayInput ? InvertArrayPatternForExclude<p, arrayInput, empty, IsReadonlyArray<arrayInput>> : never : IsPlainObject<p> extends true ? i extends object ? [keyof p & keyof i] extends [never] ? empty : OptionalKeys<p> extends infer optKeys ? [optKeys] extends [never] ? { | ||
readonly [k in keyof p]: k extends keyof i ? InvertPatternForExcludeInternal<p[k], i[k], empty> : InvertPatternInternal<p[k], unknown>; | ||
} : Compute<{ | ||
readonly [k in Exclude<keyof p, optKeys>]: k extends keyof i ? InvertPatternForExcludeInternal<p[k], i[k], empty> : InvertPattern<p[k]>; | ||
readonly [k in Exclude<keyof p, optKeys>]: k extends keyof i ? InvertPatternForExcludeInternal<p[k], i[k], empty> : InvertPatternInternal<p[k], unknown>; | ||
} & { | ||
readonly [k in Cast<optKeys, keyof p>]?: k extends keyof i ? InvertPatternForExcludeInternal<p[k], i[k], empty> : InvertPattern<p[k]>; | ||
readonly [k in Extract<optKeys, keyof p>]?: k extends keyof i ? InvertPatternForExcludeInternal<p[k], i[k], empty> : InvertPatternInternal<p[k], unknown>; | ||
}> : empty : empty : empty; | ||
export {}; |
@@ -1,31 +0,13 @@ | ||
import { Primitives, IsPlainObject, IsUnion } from './helpers.js'; | ||
export type IsMatching<a, p> = true extends IsUnion<a> | IsUnion<p> ? true extends (p extends any ? (a extends any ? IsMatching<a, p> : never) : never) ? true : false : unknown extends p ? true : p extends Primitives ? p extends a ? true : false : [p, a] extends [readonly any[], readonly any[]] ? [p, a] extends [ | ||
readonly [infer p1, infer p2, infer p3, infer p4, infer p5], | ||
readonly [infer a1, infer a2, infer a3, infer a4, infer a5] | ||
] ? [ | ||
IsMatching<a1, p1>, | ||
IsMatching<a2, p2>, | ||
IsMatching<a3, p3>, | ||
IsMatching<a4, p4>, | ||
IsMatching<a5, p5> | ||
] extends [true, true, true, true, true] ? true : false : [p, a] extends [ | ||
readonly [infer p1, infer p2, infer p3, infer p4], | ||
readonly [infer a1, infer a2, infer a3, infer a4] | ||
] ? [ | ||
IsMatching<a1, p1>, | ||
IsMatching<a2, p2>, | ||
IsMatching<a3, p3>, | ||
IsMatching<a4, p4> | ||
] extends [true, true, true, true] ? true : false : [p, a] extends [ | ||
readonly [infer p1, infer p2, infer p3], | ||
readonly [infer a1, infer a2, infer a3] | ||
] ? [IsMatching<a1, p1>, IsMatching<a2, p2>, IsMatching<a3, p3>] extends [ | ||
true, | ||
true, | ||
true | ||
] ? true : false : [p, a] extends [ | ||
readonly [infer p1, infer p2], | ||
readonly [infer a1, infer a2] | ||
] ? [IsMatching<a1, p1>, IsMatching<a2, p2>] extends [true, true] ? true : false : [p, a] extends [readonly [infer p1], readonly [infer a1]] ? IsMatching<a1, p1> : p extends a ? true : false : IsPlainObject<p> extends true ? true extends (a extends any ? [keyof p & keyof a] extends [never] ? false : { | ||
[k in keyof p & keyof a]: IsMatching<a[k], p[k]>; | ||
}[keyof p & keyof a] extends true ? true : false : never) ? true : false : p extends a ? true : false; | ||
import { Primitives, IsPlainObject, IsUnion, ValueOf, Length, IsLiteral, All, Equal } from './helpers.js'; | ||
type IsMatchingTuple<a extends readonly any[], b extends readonly any[]> = [ | ||
a, | ||
b | ||
] extends [readonly [], readonly []] ? true : [a, b] extends [ | ||
readonly [infer a1, ...infer aRest], | ||
readonly [infer b1, ...infer bRest] | ||
] ? IsMatching<a1, b1> extends true ? IsMatchingTuple<aRest, bRest> : false : false; | ||
type IsMatchingArray<a extends readonly any[], b extends readonly any[]> = b extends readonly [] ? true : b extends readonly [infer b1, ...infer bRest] ? a extends readonly [infer a1, ...infer aRest] ? IsMatching<a1, b1> extends true ? IsMatchingArray<aRest, bRest> : false : a extends readonly [] ? false : IsMatching<ValueOf<a>, b1> extends true ? IsMatchingArray<a, bRest> : false : b extends readonly [...infer bInit, infer b1] ? a extends readonly [...infer aInit, infer a1] ? IsMatching<a1, b1> extends true ? IsMatchingArray<aInit, bInit> : false : a extends readonly [] ? false : IsMatching<ValueOf<a>, b1> extends true ? IsMatchingArray<a, bInit> : false : IsMatching<ValueOf<a>, ValueOf<b>>; | ||
export type IsMatching<a, b> = true extends IsUnion<a> | IsUnion<b> ? true extends (b extends any ? (a extends any ? IsMatching<a, b> : never) : never) ? true : false : unknown extends b ? true : b extends Primitives ? a extends b ? true : b extends a ? true : false : Equal<a, b> extends true ? true : b extends readonly any[] ? a extends readonly any[] ? All<[IsLiteral<Length<a>>, IsLiteral<Length<b>>]> extends true ? Equal<Length<a>, Length<b>> extends false ? false : IsMatchingTuple<a, b> : IsMatchingArray<a, b> : false : IsPlainObject<b> extends true ? true extends (a extends any ? [keyof b & keyof a] extends [never] ? false : { | ||
[k in keyof b & keyof a]: IsMatching<a[k], b[k]>; | ||
}[keyof b & keyof a] extends true ? true : false : never) ? true : false : b extends a ? true : false; | ||
export {}; |
import type * as symbols from '../internals/symbols.js'; | ||
import type { Pattern } from './Pattern.js'; | ||
import type { ExtractPreciseValue } from './ExtractPreciseValue.js'; | ||
import type { Pattern, MatchedValue } from './Pattern.js'; | ||
import type { InvertPatternForExclude, InvertPattern } from './InvertPattern.js'; | ||
import type { DeepExclude } from './DeepExclude.js'; | ||
import type { WithDefault, Union, GuardValue, IsNever } from './helpers.js'; | ||
import type { Union, GuardValue, IsNever } from './helpers.js'; | ||
import type { FindSelected } from './FindSelected.js'; | ||
export type MatchedValue<a, invpattern> = WithDefault<ExtractPreciseValue<a, invpattern>, a>; | ||
export type PickReturnValue<a, b> = a extends symbols.unset ? b : a; | ||
@@ -13,2 +11,5 @@ type NonExhaustiveError<i> = { | ||
} & i; | ||
type TSPatternError<i> = { | ||
__nonExhaustive: never; | ||
} & i; | ||
/** | ||
@@ -18,3 +19,3 @@ * #### Match | ||
*/ | ||
export type Match<i, o, patternValueTuples extends any[] = [], inferredOutput = never> = { | ||
export type Match<i, o, handledCases extends any[] = [], inferredOutput = never> = { | ||
/** | ||
@@ -26,3 +27,3 @@ * `.with(pattern, handler)` Registers a pattern and an handler function which | ||
**/ | ||
with<p extends Pattern<i>, c, value extends MatchedValue<i, InvertPattern<p>>>( | ||
with<const p extends Pattern<i>, c, value extends MatchedValue<i, InvertPattern<p, i>>, excluded = InvertPatternForExclude<p, value>>( | ||
/** | ||
@@ -36,15 +37,15 @@ * HACK: Using `IsNever<p>` here is a hack to | ||
*/ | ||
pattern: IsNever<p> extends true ? Pattern<i> : p, handler: (selections: FindSelected<value, p>, value: value) => PickReturnValue<o, c>): [InvertPatternForExclude<p, value>] extends [infer excluded] ? Match<Exclude<i, excluded>, o, [ | ||
...patternValueTuples, | ||
pattern: IsNever<p> extends true ? Pattern<i> : p, handler: (selections: FindSelected<value, p>, value: value) => PickReturnValue<o, c>): Match<Exclude<i, excluded>, o, [ | ||
...handledCases, | ||
excluded | ||
], Union<inferredOutput, c>> : never; | ||
with<p1 extends Pattern<i>, p2 extends Pattern<i>, c, p extends p1 | p2, value extends p extends any ? MatchedValue<i, InvertPattern<p>> : never>(p1: p1, p2: p2, handler: (value: value) => PickReturnValue<o, c>): [ | ||
], Union<inferredOutput, c>>; | ||
with<const p1 extends Pattern<i>, const p2 extends Pattern<i>, c, p extends p1 | p2, value extends p extends any ? MatchedValue<i, InvertPattern<p, i>> : never>(p1: p1, p2: p2, handler: (value: value) => PickReturnValue<o, c>): [ | ||
InvertPatternForExclude<p1, value>, | ||
InvertPatternForExclude<p2, value> | ||
] extends [infer excluded1, infer excluded2] ? Match<Exclude<i, excluded1 | excluded2>, o, [ | ||
...patternValueTuples, | ||
...handledCases, | ||
excluded1, | ||
excluded2 | ||
], Union<inferredOutput, c>> : never; | ||
with<p1 extends Pattern<i>, p2 extends Pattern<i>, p3 extends Pattern<i>, ps extends Pattern<i>[], c, p extends p1 | p2 | p3 | ps[number], value extends p extends any ? MatchedValue<i, InvertPattern<p>> : never>(...args: [ | ||
with<const p1 extends Pattern<i>, const p2 extends Pattern<i>, const p3 extends Pattern<i>, const ps extends readonly Pattern<i>[], c, p extends p1 | p2 | p3 | ps[number], value extends MatchedValue<i, InvertPattern<p, i>>>(...args: [ | ||
p1: p1, | ||
@@ -66,3 +67,3 @@ p2: p2, | ||
] ? Match<Exclude<i, excluded1 | excluded2 | excluded3 | Extract<excludedRest, any[]>[number]>, o, [ | ||
...patternValueTuples, | ||
...handledCases, | ||
excluded1, | ||
@@ -73,6 +74,6 @@ excluded2, | ||
], Union<inferredOutput, c>> : never; | ||
with<pat extends Pattern<i>, pred extends (value: MatchedValue<i, InvertPattern<pat>>) => unknown, c, value extends GuardValue<pred>>(pattern: pat, predicate: pred, handler: (selections: FindSelected<value, pat>, value: value) => PickReturnValue<o, c>): pred extends (value: any) => value is infer narrowed ? Match<Exclude<i, narrowed>, o, [ | ||
...patternValueTuples, | ||
with<const pat extends Pattern<i>, pred extends (value: MatchedValue<i, InvertPattern<pat, i>>) => unknown, c, value extends GuardValue<pred>>(pattern: pat, predicate: pred, handler: (selections: FindSelected<value, pat>, value: value) => PickReturnValue<o, c>): pred extends (value: any) => value is infer narrowed ? Match<Exclude<i, narrowed>, o, [ | ||
...handledCases, | ||
narrowed | ||
], Union<inferredOutput, c>> : Match<i, o, patternValueTuples, Union<inferredOutput, c>>; | ||
], Union<inferredOutput, c>> : Match<i, o, handledCases, Union<inferredOutput, c>>; | ||
/** | ||
@@ -85,5 +86,5 @@ * `.when(predicate, handler)` Registers a predicate function and an handler function. | ||
when<pred extends (value: i) => unknown, c, value extends GuardValue<pred>>(predicate: pred, handler: (value: value) => PickReturnValue<o, c>): pred extends (value: any) => value is infer narrowed ? Match<Exclude<i, narrowed>, o, [ | ||
...patternValueTuples, | ||
...handledCases, | ||
narrowed | ||
], Union<inferredOutput, c>> : Match<i, o, patternValueTuples, Union<inferredOutput, c>>; | ||
], Union<inferredOutput, c>> : Match<i, o, handledCases, Union<inferredOutput, c>>; | ||
/** | ||
@@ -109,3 +110,3 @@ * `.otherwise()` takes a function returning the **default value**, and | ||
* */ | ||
exhaustive: DeepExcludeAll<i, patternValueTuples> extends infer remainingCases ? [remainingCases] extends [never] ? () => PickReturnValue<o, inferredOutput> : NonExhaustiveError<remainingCases> : never; | ||
exhaustive: DeepExcludeAll<i, handledCases> extends infer remainingCases ? [remainingCases] extends [never] ? () => PickReturnValue<o, inferredOutput> : NonExhaustiveError<remainingCases> : never; | ||
/** | ||
@@ -115,2 +116,8 @@ * `.run()` runs the pattern matching expression and return the result value. | ||
run(): PickReturnValue<o, inferredOutput>; | ||
/** | ||
* `.returnType<T>()` Lets you specific a return type for all your code branches. | ||
* | ||
* [Read documentation for `.returnType()` on GitHub](https://github.com/gvergnaud/ts-pattern#returnType) | ||
* */ | ||
returnType: [inferredOutput] extends [never] ? <output>() => Match<i, output, handledCases> : TSPatternError<'calling `.returnType<T>()` is only allowed directly after `match(...)`.'>; | ||
}; | ||
@@ -135,5 +142,5 @@ /** | ||
type DeepExcludeAll<a, tupleList extends any[]> = [a] extends [never] ? never : tupleList extends [infer excluded, ...infer tail] ? DeepExcludeAll<DeepExclude<a, excluded>, tail> : a; | ||
type MakeTuples<ps extends any[], value> = { | ||
type MakeTuples<ps extends readonly any[], value> = { | ||
-readonly [index in keyof ps]: InvertPatternForExclude<ps[index], value>; | ||
}; | ||
export {}; |
import type * as symbols from '../internals/symbols.js'; | ||
import { Primitives } from './helpers.js'; | ||
import { MergeUnion, Primitives, WithDefault } from './helpers.js'; | ||
import { None, Some, SelectionType } from './FindSelected.js'; | ||
export type MatcherType = 'not' | 'optional' | 'or' | 'and' | 'array' | 'select' | 'default'; | ||
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<input, narrowed, matcherType extends MatcherType, selections extends SelectionType, excluded> = { | ||
@@ -22,7 +24,13 @@ match: <I>(value: I | input) => MatchResult; | ||
export interface Matcher<input, narrowed, matcherType extends MatcherType = 'default', selections extends SelectionType = None, excluded = narrowed> { | ||
[symbols.matcher](): MatcherProtocol<input, narrowed, matcherType, selections, excluded>; | ||
[matcher](): MatcherProtocol<input, narrowed, matcherType, selections, excluded>; | ||
[symbols.isVariadic]?: boolean; | ||
} | ||
export type MatchedValue<a, invpattern> = WithDefault<ExtractPreciseValue<a, invpattern>, a>; | ||
export type AnyMatcher = Matcher<any, any, any, any, any>; | ||
type UnknownMatcher = Matcher<unknown, unknown, any, any>; | ||
export type CustomP<input, pattern, narrowedOrFn> = Matcher<input, pattern, 'custom', None, narrowedOrFn>; | ||
export type ArrayP<input, p> = Matcher<input, p, 'array'>; | ||
export type OptionalP<input, p> = Matcher<input, p, 'optional'>; | ||
export type ArrayP<input, p> = Matcher<input, p, 'array'>; | ||
export type MapP<input, pkey, pvalue> = Matcher<input, [pkey, pvalue], 'map'>; | ||
export type SetP<input, p> = Matcher<input, p, 'set'>; | ||
export type AndP<input, ps> = Matcher<input, ps, 'and'>; | ||
@@ -35,8 +43,8 @@ export type OrP<input, ps> = Matcher<input, ps, 'or'>; | ||
export type AnonymousSelectP = SelectP<symbols.anonymousSelectKey>; | ||
export interface ToExclude<a> { | ||
[symbols.toExclude]: a; | ||
export interface Override<a> { | ||
[symbols.override]: a; | ||
} | ||
export type UnknownPattern = readonly [] | readonly [UnknownPattern, ...UnknownPattern[]] | { | ||
readonly [k: string]: UnknownPattern; | ||
} | Set<UnknownPattern> | Map<unknown, UnknownPattern> | Primitives | UnknownMatcher; | ||
export type UnknownPattern = readonly [] | readonly [unknown, ...unknown[]] | readonly [...unknown[], unknown] | { | ||
readonly [k: string]: unknown; | ||
} | Primitives | UnknownMatcher; | ||
/** | ||
@@ -53,7 +61,10 @@ * `Pattern<a>` is the generic type for patterns matching a value of type `a`. A pattern can be any (nested) javascript value. | ||
*/ | ||
export type Pattern<a> = Matcher<a, unknown, any, any> | (a extends Primitives ? a : unknown extends a ? UnknownPattern : a extends readonly (infer i)[] ? a extends readonly [any, ...any] ? { | ||
export type Pattern<a> = unknown extends a ? UnknownPattern : PatternInternal<a>; | ||
export type PatternInternal<a, objs = Exclude<a, Primitives | Map<any, any> | Set<any> | readonly any[]>, arrays = Extract<a, readonly any[]>, primitives = Extract<a, Primitives>> = Matcher<a, unknown, any, any> | ([objs] extends [never] ? never : ObjectPattern<MergeUnion<objs>>) | ([arrays] extends [never] ? never : ArrayPattern<arrays>) | primitives; | ||
type ObjectPattern<a> = { | ||
readonly [k in keyof a]?: Pattern<Exclude<a[k], undefined>>; | ||
}; | ||
type ArrayPattern<a> = a extends readonly (infer i)[] ? a extends readonly [any, ...any] ? { | ||
readonly [index in keyof a]: Pattern<a[index]>; | ||
} : readonly [] | readonly [Pattern<i>, ...Pattern<i>[]] : a extends Map<infer k, infer v> ? Map<k, Pattern<v>> : a extends Set<infer v> ? Set<Pattern<v>> : a extends object ? { | ||
readonly [k in keyof a]?: Pattern<Exclude<a[k], undefined>>; | ||
} : a); | ||
} : readonly [] | readonly [Pattern<i>, ...Pattern<i>[]] | readonly [...Pattern<i>[], Pattern<i>] : never; | ||
export {}; |
{ | ||
"name": "ts-pattern", | ||
"version": "4.3.0", | ||
"version": "5.0.0-rc.0", | ||
"description": " The exhaustive Pattern Matching library for TypeScript.", | ||
@@ -64,7 +64,7 @@ "type": "module", | ||
"microbundle": "^0.15.1", | ||
"prettier": "^2.5.1", | ||
"prettier": "^2.8.8", | ||
"rimraf": "^5.0.0", | ||
"ts-jest": "^27.1.2", | ||
"typescript": "^4.8.3" | ||
"typescript": "^5.0.4" | ||
} | ||
} | ||
} |
@@ -569,3 +569,3 @@ <h1 align="center">TS-Pattern</h1> | ||
const fn = (org: Plan, user: Permission) => | ||
match([org, user] as const) | ||
match([org, user]) | ||
.with(['basic', 'viewer'], () => {}) | ||
@@ -579,3 +579,3 @@ .with(['basic', 'editor'], () => {}) | ||
const fn2 = (org: Plan, user: Permission) => | ||
match([org, user] as const) | ||
match([org, user]) | ||
.with(['basic', 'viewer'], () => {}) | ||
@@ -961,5 +961,7 @@ .with(['basic', 'editor'], () => {}) | ||
### Sets | ||
### `P.set` patterns | ||
Patterns can be Sets. | ||
To match a Set, you can use `P.set(subpattern)`. | ||
It takes a sub-pattern, and will match if **all elements** inside the set | ||
match this sub-pattern. | ||
@@ -974,23 +976,17 @@ ```ts | ||
const output = match(input) | ||
.with(new Set([1, 'hello']), (set) => `Set contains 1 and 'hello'`) | ||
.with(new Set([1, 2]), (set) => `Set contains 1 and 2`) | ||
.with(new Set([P.string]), (set) => `Set contains only strings`) | ||
.with(new Set([P.number]), (set) => `Set contains only numbers`) | ||
.with(P.set(1), (set) => `Set contains only 1`) | ||
.with(P.set(P.string), (set) => `Set contains only strings`) | ||
.with(P.set(P.number), (set) => `Set contains only numbers`) | ||
.otherwise(() => ''); | ||
console.log(output); | ||
// => 'Set contains 1 and 2' | ||
// => "Set contains only numbers" | ||
``` | ||
If a Set pattern contains one single wildcard pattern, it will match if | ||
each value in the input set match the wildcard. | ||
### `P.map` patterns | ||
If a Set pattern contains several values, it will match if the | ||
input Set contains each of these values. | ||
To match a Map, you can use `P.map(keyPattern, valuePattern)`. | ||
It takes a subpattern to match against the key, a subpattern to match agains the value, and will match if **all elements** inside this map | ||
match these two sub-patterns. | ||
### Maps | ||
Patterns can be Maps. They match if the input is a Map, and if each | ||
value match the corresponding sub-pattern. | ||
```ts | ||
@@ -1008,10 +1004,7 @@ import { match, P } from 'ts-pattern'; | ||
const output = match(input) | ||
.with(new Map([['b', 2]]), (map) => `map.get('b') is 2`) | ||
.with(new Map([['a', P.string]]), (map) => `map.get('a') is a string`) | ||
.with(P.map(P.string, P.number), (map) => `map's type is Map<string, number>`) | ||
.with(P.map(P.string, P.string), (map) => `map's type is Map<string, string>`) | ||
.with( | ||
new Map([ | ||
['a', P.number], | ||
['c', P.number], | ||
]), | ||
(map) => `map.get('a') and map.get('c') are number` | ||
P.map(P.union('a', 'c'), P.number), | ||
(map) => `map's type is Map<'a' | 'c', number>` | ||
) | ||
@@ -1021,3 +1014,3 @@ .otherwise(() => ''); | ||
console.log(output); | ||
// => 'map.get('b') is 2' | ||
// => "map's type is Map<string, number>" | ||
``` | ||
@@ -1382,3 +1375,3 @@ | ||
const fn = (org: Plan, user: Permission): string => | ||
match([org, user] as const) | ||
match([org, user]) | ||
.with(['basic', 'viewer'], () => {}) | ||
@@ -1385,0 +1378,0 @@ .with(['basic', 'editor'], () => {}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
455285
1608
1
1388