Socket
Socket
Sign inDemoInstall

ts-pattern

Package Overview
Dependencies
Maintainers
1
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ts-pattern - npm Package Compare versions

Comparing version 1.1.0 to 2.0.1-next.0

lib/PatternType.d.ts

18

lib/index.d.ts

@@ -1,7 +0,12 @@

import { Pattern, __, when, not, select } from './types/Pattern';
import { Match } from './types/Match';
import type { Pattern, SelectPattern, GuardPattern, NotPattern, GuardFunction } from './types/Pattern';
import type { Match, ExhaustiveMatch } from './types/Match';
import { __ } from './PatternType';
import { DistributeUnions } from './types/DistributeUnions';
export declare const when: <a, b extends a = a>(predicate: GuardFunction<a, b>) => GuardPattern<a, b>;
export declare const not: <a>(pattern: Pattern<a>) => NotPattern<a>;
export declare const select: <k extends string>(key: k) => SelectPattern<k>;
/**
* # Pattern matching
**/
export { Pattern, __, when, not, select };
export { Pattern, __ };
/**

@@ -13,1 +18,8 @@ * ### match

export declare const match: <a, b = "@match/unset">(value: a) => Match<a, b>;
/**
* ### exhaustiveMatch
* creates an exhaustive match expression checking
* that **all cases are handled**. `when` predicates
* aren't supported on exhaustive matches.
**/
export declare const exhaustiveMatch: <a, b = "@match/unset">(value: a) => ExhaustiveMatch<DistributeUnions<a>, b>;

73

lib/index.js

@@ -23,8 +23,20 @@ "use strict";

exports.__esModule = true;
exports.match = exports.select = exports.not = exports.when = exports.__ = void 0;
var Pattern_1 = require("./types/Pattern");
exports.__ = Pattern_1.__;
exports.when = Pattern_1.when;
exports.not = Pattern_1.not;
exports.select = Pattern_1.select;
exports.exhaustiveMatch = exports.match = exports.__ = exports.select = exports.not = exports.when = void 0;
var PatternType_1 = require("./PatternType");
exports.__ = PatternType_1.__;
var when = function (predicate) { return ({
__patternKind: PatternType_1.PatternType.Guard,
__when: predicate
}); };
exports.when = when;
var not = function (pattern) { return ({
__patternKind: PatternType_1.PatternType.Not,
__pattern: pattern
}); };
exports.not = not;
var select = function (key) { return ({
__patternKind: PatternType_1.PatternType.Select,
__key: key
}); };
exports.select = select;
/**

@@ -35,6 +47,15 @@ * ### match

*/
exports.match = function (value) {
var match = function (value) {
return builder(value, []);
};
exports.match = match;
/**
* ### exhaustiveMatch
* creates an exhaustive match expression checking
* that **all cases are handled**. `when` predicates
* aren't supported on exhaustive matches.
**/
var exhaustiveMatch = function (value) { return builder(value, []); };
exports.exhaustiveMatch = exhaustiveMatch;
/**
* ### builder

@@ -78,3 +99,3 @@ * This is the implementation of our pattern matching, using the

{
test: matchPattern(Pattern_1.__),
test: matchPattern(PatternType_1.__),
handler: handler,

@@ -91,3 +112,10 @@ select: function () { return ({}); }

if (!entry) {
throw new Error("Pattern matching error: no pattern matches value " + value);
var displayedValue = void 0;
try {
displayedValue = JSON.stringify(value);
}
catch (e) {
displayedValue = value;
}
throw new Error("Pattern matching error: no pattern matches value " + displayedValue);
}

@@ -98,8 +126,9 @@ return entry.handler(value, entry.select(value));

var isObject = function (value) {
return value && typeof value === 'object';
return Boolean(value && typeof value === 'object');
};
var isArray = function (value) { return Array.isArray(value); };
var isGuardPattern = function (x) {
var pattern = x;
return (pattern &&
pattern.__patternKind === Pattern_1.PatternType.Guard &&
pattern.__patternKind === PatternType_1.PatternType.Guard &&
typeof pattern.__when === 'function');

@@ -109,7 +138,7 @@ };

var pattern = x;
return pattern && pattern.__patternKind === Pattern_1.PatternType.Not;
return pattern && pattern.__patternKind === PatternType_1.PatternType.Not;
};
var isSelectPattern = function (x) {
var pattern = x;
return pattern && pattern.__patternKind === Pattern_1.PatternType.Select;
return pattern && pattern.__patternKind === PatternType_1.PatternType.Select;
};

@@ -121,9 +150,9 @@ var isListPattern = function (x) {

var matchPattern = function (pattern) { return function (value) {
if (pattern === Pattern_1.__ || isSelectPattern(pattern))
if (pattern === PatternType_1.__ || isSelectPattern(pattern))
return true;
if (pattern === Pattern_1.__.string)
if (pattern === PatternType_1.__.string)
return typeof value === 'string';
if (pattern === Pattern_1.__.boolean)
if (pattern === PatternType_1.__.boolean)
return typeof value === 'boolean';
if (pattern === Pattern_1.__.number) {
if (pattern === PatternType_1.__.number) {
return typeof value === 'number' && !Number.isNaN(value);

@@ -135,7 +164,7 @@ }

return !matchPattern(pattern.__pattern)(value);
if (isListPattern(pattern) && Array.isArray(value))
if (isListPattern(pattern) && isArray(value))
return value.every(function (v) { return matchPattern(pattern[0])(v); });
if (typeof pattern !== typeof value)
return false;
if (Array.isArray(pattern) && Array.isArray(value)) {
if (isArray(pattern) && isArray(value)) {
return pattern.length === value.length

@@ -157,3 +186,3 @@ ? pattern.every(function (subPattern, i) { return matchPattern(subPattern)(value[i]); })

? patternValues.every(function (subPattern) {
return Object.values(Pattern_1.__).includes(subPattern)
return Object.values(PatternType_1.__).includes(subPattern)
? matchPattern([subPattern])(allValues_1)

@@ -176,3 +205,3 @@ : value.has(subPattern);

return _a = {}, _a[pattern.__key] = value, _a;
if (isListPattern(pattern) && Array.isArray(value))
if (isListPattern(pattern) && isArray(value))
return value

@@ -186,3 +215,3 @@ .map(function (v) { return selectWithPattern(pattern[0])(v); })

}, {});
if (Array.isArray(pattern) && Array.isArray(value))
if (isArray(pattern) && isArray(value))
return pattern.length <= value.length

@@ -189,0 +218,0 @@ ? pattern.reduce(function (acc, subPattern, i) {

@@ -1,8 +0,24 @@

import { PatternType, __, Primitives } from './Pattern';
import { ExcludeIfContainsNever, LeastUpperBound } from './helpers';
import type { PatternType, __ } from '../PatternType';
import type { Primitives } from './Pattern';
import type { ExcludeIfContainsNever, LeastUpperBound } from './helpers';
export declare type ExtractPreciseValue<a, b> = ExcludeIfContainsNever<b extends [] ? [] : b extends typeof __ ? a : b extends {
valueKind: PatternType.Not;
value: infer b1;
} ? Exclude<a, b1> : b extends [infer b1, infer b2, infer b3, infer b4, infer b5] ? a extends [infer a1, infer a2, infer a3, infer a4, infer a5] ? [ExtractPreciseValue<a1, b1>, ExtractPreciseValue<a2, b2>, ExtractPreciseValue<a3, b3>, ExtractPreciseValue<a4, b4>, ExtractPreciseValue<a5, b5>] : LeastUpperBound<a, b> : b extends [infer b1, infer b2, infer b3, infer b4] ? a extends [infer a1, infer a2, infer a3, infer a4] ? [ExtractPreciseValue<a1, b1>, ExtractPreciseValue<a2, b2>, ExtractPreciseValue<a3, b3>, ExtractPreciseValue<a4, b4>] : LeastUpperBound<a, b> : b extends [infer b1, infer b2, infer b3] ? a extends [infer a1, infer a2, infer a3] ? [ExtractPreciseValue<a1, b1>, ExtractPreciseValue<a2, b2>, ExtractPreciseValue<a3, b3>] : LeastUpperBound<a, b> : b extends [infer b1, infer b2] ? a extends [infer a1, infer a2] ? [ExtractPreciseValue<a1, b1>, ExtractPreciseValue<a2, b2>] : LeastUpperBound<a, b> : b extends (infer b1)[] ? a extends (infer a1)[] ? ExtractPreciseValue<a1, b1>[] : 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> : b extends object ? a extends any[] | Set<any> | Map<any, any> | Primitives ? LeastUpperBound<a, b> : b extends a ? b : a extends b ? a : {
} ? Exclude<a, b1> : b extends [infer b1, infer b2, infer b3, infer b4, infer b5] ? a extends [infer a1, infer a2, infer a3, infer a4, infer a5] ? [
ExtractPreciseValue<a1, b1>,
ExtractPreciseValue<a2, b2>,
ExtractPreciseValue<a3, b3>,
ExtractPreciseValue<a4, b4>,
ExtractPreciseValue<a5, b5>
] : LeastUpperBound<a, b> : b extends [infer b1, infer b2, infer b3, infer b4] ? a extends [infer a1, infer a2, infer a3, infer a4] ? [
ExtractPreciseValue<a1, b1>,
ExtractPreciseValue<a2, b2>,
ExtractPreciseValue<a3, b3>,
ExtractPreciseValue<a4, b4>
] : LeastUpperBound<a, b> : b extends [infer b1, infer b2, infer b3] ? a extends [infer a1, infer a2, infer a3] ? [
ExtractPreciseValue<a1, b1>,
ExtractPreciseValue<a2, b2>,
ExtractPreciseValue<a3, b3>
] : LeastUpperBound<a, b> : b extends [infer b1, infer b2] ? a extends [infer a1, infer a2] ? [ExtractPreciseValue<a1, b1>, ExtractPreciseValue<a2, b2>] : LeastUpperBound<a, b> : b extends (infer b1)[] ? a extends (infer a1)[] ? ExtractPreciseValue<a1, b1>[] : 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> : b extends object ? a extends any[] | Set<any> | Map<any, any> | Primitives ? LeastUpperBound<a, b> : b extends a ? b : a extends b ? a : {
[k in keyof Required<a>]: k extends keyof b ? ExtractPreciseValue<a[k], b[k]> : a[k];
} : LeastUpperBound<a, b>>;

@@ -1,2 +0,3 @@

export declare type ValueOf<a> = a[keyof a];
export declare type ValueOf<a> = a extends any[] ? a[number] : a[keyof a];
export declare type Values<a extends object> = UnionToTuple<ValueOf<a>>;
/**

@@ -21,2 +22,29 @@ * ### LeastUpperBound

export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
declare type IsLiteralString<T extends string> = string extends T ? false : true;
declare type IsLiteralNumber<T extends number> = number extends T ? false : true;
declare type IsLiteralBoolean<T extends boolean> = boolean extends T ? false : true;
export declare type IsLiteral<T> = T extends string ? IsLiteralString<T> : T extends number ? IsLiteralNumber<T> : T extends boolean ? IsLiteralBoolean<T> : false;
export declare type IsUnion<a> = [a] extends [UnionToIntersection<a>] ? false : true;
export declare type ContainsUnion<a> = IsUnion<a> extends true ? true : a extends object ? false extends ValueOf<{
[k in keyof a]: ContainsUnion<a[k]>;
}> ? false : true : false;
declare type NeverKeys<o> = ValueOf<{
[k in keyof o]: [o[k]] extends [never] ? k : never;
}>;
declare type RemoveNeverKeys<o> = Omit<o, NeverKeys<o>>;
export declare type ExcludeUnion<a> = IsUnion<a> extends true ? never : a extends object ? RemoveNeverKeys<{
[k in keyof a]: ExcludeUnion<a[k]>;
}> : a;
export declare type UnionToTuple<T> = UnionToIntersection<T extends any ? (t: T) => T : never> extends (_: any) => infer W ? [...UnionToTuple<Exclude<T, W>>, W] : [];
export declare type Cast<a, b> = a extends b ? a : never;
export declare type Flatten<xs extends any[]> = xs extends [infer head, ...(infer tail)] ? [...Cast<head, any[]>, ...Flatten<tail>] : [];
export declare type Equal<X, Y> = X extends Y ? (Y extends X ? true : false) : false;
export declare type Expect<T extends true> = T;
export declare type IsAny<a> = [a] extends [never] ? false : Equal<a, any>;
export declare type Length<it extends any[]> = it['length'];
export declare type Iterator<n extends number, it extends any[] = []> = it['length'] extends n ? it : Iterator<n, [any, ...it]>;
export declare type Next<it extends any[]> = [any, ...it];
export declare type Prev<it extends any[]> = it extends [any, ...(infer tail)] ? tail : [];
export declare type Slice<xs extends any[], it extends any[], output extends any[] = []> = Length<it> extends 0 ? output : xs extends [infer head, ...(infer tail)] ? Slice<tail, Prev<it>, [...output, head]> : output;
export declare type Drop<xs extends any[], n extends any[]> = Length<n> extends 0 ? xs : xs extends [any, ...(infer tail)] ? Drop<tail, Prev<n>> : [];
export {};

@@ -1,2 +0,3 @@

import { __, SelectPattern, GuardPattern, NotPattern, PatternType, Primitives } from './Pattern';
import type { PatternType, __ } from '../PatternType';
import type { SelectPattern, GuardPattern, NotPattern, Primitives } from './Pattern';
/**

@@ -10,4 +11,10 @@ * ### InvertPattern

value: InvertPattern<pb>;
} : p extends Primitives ? p : p extends [infer pb, infer pc, infer pd, infer pe, infer pf] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>, InvertPattern<pe>, InvertPattern<pf>] : p extends [infer pb, infer pc, infer pd, infer pe] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>, InvertPattern<pe>] : p extends [infer pb, infer pc, infer pd] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>] : p extends [infer pb, infer pc] ? [InvertPattern<pb>, InvertPattern<pc>] : p extends (infer pp)[] ? InvertPattern<pp>[] : p extends Map<infer pk, infer pv> ? Map<pk, InvertPattern<pv>> : p extends Set<infer pv> ? Set<InvertPattern<pv>> : p extends object ? {
} : p extends Primitives ? p : p extends [infer pb, infer pc, infer pd, infer pe, infer pf] ? [
InvertPattern<pb>,
InvertPattern<pc>,
InvertPattern<pd>,
InvertPattern<pe>,
InvertPattern<pf>
] : p extends [infer pb, infer pc, infer pd, infer pe] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>, InvertPattern<pe>] : p extends [infer pb, infer pc, infer pd] ? [InvertPattern<pb>, InvertPattern<pc>, InvertPattern<pd>] : p extends [infer pb, infer pc] ? [InvertPattern<pb>, InvertPattern<pc>] : p extends (infer pp)[] ? InvertPattern<pp>[] : p extends Map<infer pk, infer pv> ? Map<pk, InvertPattern<pv>> : p extends Set<infer pv> ? Set<InvertPattern<pv>> : p extends object ? {
[k in keyof p]: InvertPattern<p[k]>;
} : p;

@@ -1,37 +0,7 @@

import { Pattern, SelectPattern, GuardValue } from './Pattern';
import { ExtractPreciseValue } from './ExtractPreciseValue';
import { InvertPattern } from './InvertPattern';
import { ValueOf, UnionToIntersection } from './helpers';
import type { Pattern, GuardValue, ExhaustivePattern } from './Pattern';
import type { ExtractPreciseValue } from './ExtractPreciseValue';
import type { InvertPattern } from './InvertPattern';
import type { UnionToIntersection } from './helpers';
import type { FindSelected } from './FindSelected';
export declare type MatchedValue<a, p extends Pattern<a>> = ExtractPreciseValue<a, InvertPattern<p>> extends never ? a : ExtractPreciseValue<a, InvertPattern<p>>;
declare type FindSelected<a, b> = b extends SelectPattern<infer Key> ? {
[k in Key]: a;
} : [a, b] extends [(infer aa)[], [infer p]] ? {
[k in keyof FindSelected1<aa, p>]: FindSelected1<aa, p>[k][];
} : [a, b] extends [object, object] ? ValueOf<{
[k in keyof a & keyof b]: FindSelected1<a[k], b[k]>;
}> : never;
declare type FindSelected1<a, b> = b extends SelectPattern<infer Key> ? {
[k in Key]: a;
} : [a, b] extends [(infer aa)[], [infer p]] ? {
[k in keyof FindSelected2<aa, p>]: FindSelected2<aa, p>[k][];
} : [a, b] extends [object, object] ? ValueOf<{
[k in keyof a & keyof b]: FindSelected2<a[k], b[k]>;
}> : never;
declare type FindSelected2<a, b> = b extends SelectPattern<infer Key> ? {
[k in Key]: a;
} : [a, b] extends [(infer aa)[], [infer p]] ? {
[k in keyof FindSelected3<aa, p>]: FindSelected3<aa, p>[k][];
} : [a, b] extends [object, object] ? ValueOf<{
[k in keyof a & keyof b]: FindSelected3<a[k], b[k]>;
}> : never;
declare type FindSelected3<a, b> = b extends SelectPattern<infer Key> ? {
[k in Key]: a;
} : [a, b] extends [(infer aa)[], [infer p]] ? {
[k in keyof FindSelected4<aa, p>]: FindSelected4<aa, p>[k][];
} : [a, b] extends [object, object] ? ValueOf<{
[k in keyof a & keyof b]: FindSelected4<a[k], b[k]>;
}> : never;
declare type FindSelected4<a, b> = b extends SelectPattern<infer Key> ? {
[k in Key]: a;
} : never;
export declare type ExtractSelections<a, p extends Pattern<a>> = UnionToIntersection<FindSelected<MatchedValue<a, p>, p>>;

@@ -74,2 +44,34 @@ export declare type Unset = '@match/unset';

};
declare type NonExhaustivePattern<i> = {
__nonExhaustive: never;
} & i;
/**
* ### ExhaustiveMatch
* An interface to create an exhaustive pattern matching clause.
*/
export declare type ExhaustiveMatch<i, o> = {
/**
* ### Match.with
* If the data matches the pattern provided as first argument,
* use this branch and execute the handler function.
**/
with<p extends ExhaustivePattern<i>, c>(pattern: p, handler: (value: MatchedValue<i, p>, selections: ExtractSelections<i, p>) => PickReturnValue<o, c>): ExhaustiveMatch<Exclude<i, ExtractPreciseValue<i, InvertPattern<p>>>, PickReturnValue<o, c>>;
/**
* ### Match.otherwise
* takes a function returning the default value
* and return the matched result.
*
* Equivalent to `.with(__, () => x).run()`
**/
otherwise: <c>(handler: () => PickReturnValue<o, c>) => PickReturnValue<o, c>;
/**
* ### Match.run
* Runs the pattern matching and return a value.
*
* If this is of type `NonExhaustivePattern`, it means you aren't matching
* every cases, and you should probably add a another `.with(...)` clause
* to prevent potential runtime errors.
* */
run: [i] extends [never] ? () => o : NonExhaustivePattern<i>;
};
export {};

@@ -1,9 +0,2 @@

export declare enum PatternType {
String = "@match/string",
Number = "@match/number",
Boolean = "@match/boolean",
Guard = "@match/guard",
Not = "@match/not",
Select = "@match/select"
}
import type { __, PatternType } from '../PatternType';
export declare type Primitives = number | boolean | string | undefined | null | symbol | bigint;

@@ -27,3 +20,3 @@ /**

};
declare type SpecialPattern<a> = a extends number ? typeof __.number | typeof __ : a extends string ? typeof __.string | typeof __ : a extends boolean ? typeof __.boolean | typeof __ : typeof __;
declare type WildCardPattern<a> = a extends number ? typeof __.number | typeof __ : a extends string ? typeof __.string | typeof __ : a extends boolean ? typeof __.boolean | typeof __ : typeof __;
/**

@@ -34,29 +27,34 @@ * ### Pattern

*/
export declare type Pattern<a> = SelectPattern<string> | GuardPattern<a> | NotPattern<a | any> | SpecialPattern<a> | (a extends Primitives ? a : a extends [infer b, infer c, infer d, infer e, infer f] ? [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>, Pattern<f>] : a extends [infer b, infer c, infer d, infer e] ? [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>] : a extends [infer b, infer c, infer d] ? [Pattern<b>, Pattern<c>, Pattern<d>] : a extends [infer b, infer c] ? [Pattern<b>, Pattern<c>] : a extends (infer b)[] ? [] | [Pattern<b>] | [Pattern<b>, Pattern<b>] | [Pattern<b>, Pattern<b>, Pattern<b>] | [Pattern<b>, Pattern<b>, Pattern<b>, Pattern<b>] | [Pattern<b>, Pattern<b>, Pattern<b>, Pattern<b>, Pattern<b>] : a extends Map<infer k, infer v> ? Map<k, Pattern<v>> : a extends Set<infer v> ? Set<Pattern<v>> : a extends object ? {
export declare type Pattern<a> = SelectPattern<string> | GuardPattern<a> | NotPattern<a | any> | WildCardPattern<a> | (a extends Primitives ? a : a extends [infer b, infer c, infer d, infer e, infer f] ? [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>, Pattern<f>] : a extends [infer b, infer c, infer d, infer e] ? [Pattern<b>, Pattern<c>, Pattern<d>, Pattern<e>] : a extends [infer b, infer c, infer d] ? [Pattern<b>, Pattern<c>, Pattern<d>] : a extends [infer b, infer c] ? [Pattern<b>, Pattern<c>] : a extends (infer b)[] ? [] | [Pattern<b>] | [Pattern<b>, Pattern<b>] | [Pattern<b>, Pattern<b>, Pattern<b>] | [Pattern<b>, Pattern<b>, Pattern<b>, Pattern<b>] | [Pattern<b>, Pattern<b>, Pattern<b>, Pattern<b>, Pattern<b>] : a extends Map<infer k, infer v> ? Map<k, Pattern<v>> : a extends Set<infer v> ? Set<Pattern<v>> : a extends object ? {
[k in keyof a]?: Pattern<a[k]>;
} : a);
export declare const when: <a, b extends a = a>(predicate: GuardFunction<a, b>) => GuardPattern<a, b>;
export declare const not: <a>(pattern: Pattern<a>) => NotPattern<a>;
export declare const select: <k extends string>(key: k) => SelectPattern<k>;
/**
* ### Catch All wildcard
* `__` is wildcard pattern, matching **any value**.
*
* `__.string` is wildcard pattern matching any **string**.
*
* `__.number` is wildcard pattern matching any **number**.
*
* `__.boolean` is wildcard pattern matching any **boolean**.
* @example
* match(value)
* .with(__, () => 'will always match')
* .with(__.string, () => 'will match on strings only')
* .with(__.number, () => 'will match on numbers only')
* .with(__.boolean, () => 'will match on booleans only')
* ### ExhaustivePattern
* Just like the Pattern type, excluding when clauses.
*/
export declare const __: {
readonly string: PatternType.String;
readonly number: PatternType.Number;
readonly boolean: PatternType.Boolean;
};
export declare type ExhaustivePattern<a> = SelectPattern<string> | NotPattern<a | any> | WildCardPattern<a> | (a extends Primitives ? a : a extends [infer b, infer c, infer d, infer e, infer f] ? [
ExhaustivePattern<b>,
ExhaustivePattern<c>,
ExhaustivePattern<d>,
ExhaustivePattern<e>,
ExhaustivePattern<f>
] : a extends [infer b, infer c, infer d, infer e] ? [
ExhaustivePattern<b>,
ExhaustivePattern<c>,
ExhaustivePattern<d>,
ExhaustivePattern<e>
] : a extends [infer b, infer c, infer d] ? [ExhaustivePattern<b>, ExhaustivePattern<c>, ExhaustivePattern<d>] : a extends [infer b, infer c] ? [ExhaustivePattern<b>, ExhaustivePattern<c>] : a extends (infer b)[] ? [] | [ExhaustivePattern<b>] | [ExhaustivePattern<b>, ExhaustivePattern<b>] | [ExhaustivePattern<b>, ExhaustivePattern<b>, ExhaustivePattern<b>] | [
ExhaustivePattern<b>,
ExhaustivePattern<b>,
ExhaustivePattern<b>,
ExhaustivePattern<b>
] | [
ExhaustivePattern<b>,
ExhaustivePattern<b>,
ExhaustivePattern<b>,
ExhaustivePattern<b>,
ExhaustivePattern<b>
] : a extends Map<infer k, infer v> ? Map<k, ExhaustivePattern<v>> : a extends Set<infer v> ? Set<ExhaustivePattern<v>> : a extends object ? {
[k in keyof a]?: ExhaustivePattern<a[k]>;
} : a);
export {};
"use strict";
exports.__esModule = true;
exports.__ = exports.select = exports.not = exports.when = exports.PatternType = void 0;
var PatternType;
(function (PatternType) {
PatternType["String"] = "@match/string";
PatternType["Number"] = "@match/number";
PatternType["Boolean"] = "@match/boolean";
PatternType["Guard"] = "@match/guard";
PatternType["Not"] = "@match/not";
PatternType["Select"] = "@match/select";
})(PatternType = exports.PatternType || (exports.PatternType = {}));
exports.when = function (predicate) { return ({
__patternKind: PatternType.Guard,
__when: predicate
}); };
exports.not = function (pattern) { return ({
__patternKind: PatternType.Not,
__pattern: pattern
}); };
exports.select = function (key) { return ({
__patternKind: PatternType.Select,
__key: key
}); };
/**
* ### Catch All wildcard
* `__` is wildcard pattern, matching **any value**.
*
* `__.string` is wildcard pattern matching any **string**.
*
* `__.number` is wildcard pattern matching any **number**.
*
* `__.boolean` is wildcard pattern matching any **boolean**.
* @example
* match(value)
* .with(__, () => 'will always match')
* .with(__.string, () => 'will match on strings only')
* .with(__.number, () => 'will match on numbers only')
* .with(__.boolean, () => 'will match on booleans only')
*/
exports.__ = {
string: PatternType.String,
number: PatternType.Number,
boolean: PatternType.Boolean
};
{
"name": "ts-pattern",
"version": "1.1.0",
"version": "2.0.1-next.0",
"description": "Typescript pattern matching library",

@@ -8,5 +8,4 @@ "main": "lib/index.js",

"scripts": {
"clean": "rimraf lib",
"build": "tsc -d",
"prepare": "npm run test && npm run clean && npm run build",
"build": "rimraf lib && tsc -d",
"prepare": "npm run test && npm run build",
"test:values": "jest",

@@ -40,9 +39,9 @@ "test:types": "tsc --project tests/tsconfig.json",

"devDependencies": {
"@types/jest": "^25.2.3",
"jest": "^26.0.1",
"@types/jest": "^26.0.15",
"jest": "^26.6.3",
"prettier": "^2.0.5",
"rimraf": "^3.0.2",
"ts-jest": "^26.0.0",
"typescript": "^3.9.3"
"ts-jest": "^26.4.4",
"typescript": "^4.1.2"
}
}

@@ -40,3 +40,3 @@ <h1 align="center">ts-pattern</h1>

- Supports catch all (`__`) and type specific **wildcards**.
- Supports `when(<predicate>)` and `not(<pattern>)` patterns for complexe cases.
- Supports `when(<predicate>)` and `not(<pattern>)` patterns for complex cases.
- Supports properties selection, via the `select(<name>)` function.

@@ -49,3 +49,3 @@ - Tiny bundle footprint (**only 1kb**).

Pattern Matching is implemented in Elixir, Rust, Haskell, Swift and many other languages. There is [a tc39 proposal](https://github.com/tc39/proposal-pattern-matching) to add Pattern Matching to the EcmaScript specification, but it is still in stage 1 and isn't likely to land before several years (if ever). Lukily, pattern matching can be implemented in userland. `ts-pattern` Provides a typesafe pattern matching implementation that you can start using today.
Pattern Matching is implemented in Elixir, Rust, Haskell, Swift and many other languages. There is [a tc39 proposal](https://github.com/tc39/proposal-pattern-matching) to add Pattern Matching to the EcmaScript specification, but it is still in stage 1 and isn't likely to land before several years (if ever). Luckily, pattern matching can be implemented in userland. `ts-pattern` Provides a typesafe pattern matching implementation that you can start using today.

@@ -69,3 +69,3 @@ ## Installation

- [Code Sandbox Examples](#code-sandbox-examples)
- [Intro to key concepts](#intro-to-key-concepts)
- [Getting Started](#getting-started)
- [API Reference](#api-reference)

@@ -102,16 +102,17 @@ - [match](#match)

## Intro to key concepts
## Getting Started
Sometimes you want to match on two values at once. Let's say we want to
create a reducer function, we could make a switch on the event's type, but
generally an event only makes sense if we are in a certain state.
As an example, we are going to create a state reducer for a
frontend application fetching some data using an HTTP request.
To avoid unwanted state changes that could lead to bugs, **we pattern match
on both the state and the event** and return a new state.
### Example: a state reducer with ts-pattern
Our application can be in four different states: `idle`, `loading`,
`success` and `error`. Depending on which state we are in, some events
can occur. Here are all the possible types of event our application
can respond to: `fetch`, `success`, `error` and `cancel`.
I use the word `event` but you can replace it with `action` if you are used
to Redux's terminology.
### Example: a state reducer with match
```ts

@@ -131,2 +132,12 @@ type State =

Even though our application can handle 4 events, **only a subset** of these
events **make sense for each given state**. For instance we can only `cancel`
a request if we are currently in the `loading` state.
To avoid unwanted state changes that could lead to bugs, we want to create
a reducer function that **matches on both the state and the event**
and return a new state.
This is a case were `match` really shines. Instead of writing nested
switch statements, we can do that in a very expressive way:
```ts

@@ -191,3 +202,3 @@ import { match, __, not, select, when } from 'ts-pattern';

and output with `match<Input, Output>(...)` because `match` is able to
infer both of this values.
infer both of these types.

@@ -304,3 +315,3 @@ ### .with(pattern, handler)

### .match
### match

@@ -440,3 +451,3 @@ ```ts

Literals are primitive javascript values, like number, string, boolean, bigint, null, undefined, and symbol.
Literals are primitive JavaScript values, like number, string, boolean, bigint, null, undefined, and symbol.

@@ -757,5 +768,5 @@ ```ts

`ts-pattern` strongly invests on typescript's type inference to narrow
the type of your value to something that match what you would expect.
Here are a few example:
`ts-pattern` strongly invests on TypeScript's type inference to narrow
the type of your value to something that matches what you would expect.
Here are a few examples:

@@ -783,3 +794,3 @@ ```ts

.with({ type: when(() => true) }, (value) => 'ok') // value: { type: string }
.with({ type: not('hello' as 'hello') }, (value) => 'ok') // value: { type: string }
.with({ type: not('hello' as const) }, (value) => 'ok') // value: { type: string }
.with({ type: not(__.string) }, (value) => 'ok') // value: never

@@ -794,3 +805,3 @@ .with({ type: not(when(() => true)) }, (value) => 'ok') // value: { type: string }

[Pattern Matching in TypeScript with Record and Wildcard Patterns](https://medium.com/swlh/pattern-matching-in-typescript-with-record-and-wildcard-patterns-6097dd4e471d).
It made me realise pattern matching could be implemented in userland and we didn't have
It made me realize pattern matching could be implemented in userland and we didn't have
to wait for it to be added to the language itself. I'm really grateful for that 🙏

@@ -797,0 +808,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc