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 0.1.3 to 0.1.4

20

lib/index.d.ts

@@ -13,3 +13,15 @@ /**

* ### Catch All wildcard
* `__` refers to a wildcard pattern, matching any value
* `__` 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')
*/

@@ -53,3 +65,3 @@ export declare const __: {

valueKind: PatternType.Not;
pattern: InvertPattern<pb>;
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 ? {

@@ -69,4 +81,4 @@ [k in keyof p]: InvertPattern<p[k]>;

valueKind: PatternType.Not;
pattern: infer b1;
} ? Exclude<a, b1> : [a, b] extends [object, object] ? ObjectExtractMostPreciseValue<a, b> : LeastUpperBound<a, b>;
value: infer b1;
} ? Exclude<a, b1> extends never ? a : Exclude<a, b1> : b extends object ? ObjectExtractMostPreciseValue<a, b> : LeastUpperBound<a, b>;
/**

@@ -73,0 +85,0 @@ * if a key of an object has the never type,

14

lib/index.js

@@ -37,3 +37,15 @@ "use strict";

* ### Catch All wildcard
* `__` refers to a wildcard pattern, matching any value
* `__` 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')
*/

@@ -40,0 +52,0 @@ exports.__ = {

{
"name": "ts-pattern",
"version": "0.1.3",
"version": "0.1.4",
"description": "Typescript pattern matching library",

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

@@ -8,18 +8,23 @@ # Typescript Pattern

match({ type: 'hello' })
.with(__, () => 'ok')
.with(__.string, () => 'ok')
type Input = { type: string } | string;
match<Input, 'ok'>({ type: 'hello' })
.with(__, (value) => 'ok') // value: Input
.with(__.string, (value) => 'ok') // value: string
.with(
when((x) => true),
() => 'ok'
when((value) => true),
(value) => 'ok' // value: Input
)
.with(not('hello'), () => 'ok')
.with(not(__.string), () => 'ok')
.with(not(when((x) => true)), () => 'ok')
.with({ type: __ }, () => 'ok')
.with({ type: __.string }, () => 'ok')
.with({ type: when((x) => true) }, () => 'ok')
.with({ type: not('hello') }, () => 'ok')
.with({ type: not(__.string) }, () => 'ok')
.with({ type: not(when((x) => true)) }, () => 'ok');
.with(not('hello'), (value) => 'ok') // value: Input
.with(not(__.string), (value) => 'ok') // value: { type: string }
.with(not(when(() => true)), (value) => 'ok') // value: Input
.with({ type: __ }, (value) => 'ok') // value: { type: string }
.with({ type: __.string }, (value) => 'ok') // value: { type: string }
.with({ type: when(() => true) }, (value) => 'ok') // value: { type: string }
.with({ type: not('hello' as 'hello') }, (value) => 'ok') // value: { type: string }
.with({ type: not(__.string) }, (value) => 'ok') // value: { type: string }
.with({ type: not(when(() => true)) }, (value) => 'ok') // value: { type: string }
.with(not({ type: when(() => true) }), (value) => 'ok') // value: string
.with(not({ type: __.string }), (value) => 'ok') // value: string
.run();
```

@@ -15,3 +15,15 @@ /**

* ### Catch All wildcard
* `__` refers to a wildcard pattern, matching any value
* `__` 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')
*/

@@ -112,3 +124,3 @@ export const __ = {

valueKind: PatternType.Not;
pattern: InvertPattern<pb>;
value: InvertPattern<pb>;
}

@@ -192,5 +204,7 @@ : p extends Primitives

? a
: b extends { valueKind: PatternType.Not; pattern: infer b1 }
? Exclude<a, b1>
: [a, b] extends [object, object]
: b extends { valueKind: PatternType.Not; value: infer b1 }
? Exclude<a, b1> extends never
? a
: Exclude<a, b1>
: b extends object
? ObjectExtractMostPreciseValue<a, b>

@@ -197,0 +211,0 @@ : LeastUpperBound<a, b>;

import { match, __, when, not, Pattern } from '../src';
// the never type can be assigned to anything. This type prevent that
type NotNever<a> = a extends never ? never : true;
type Option<a> = { kind: 'none' } | { kind: 'some'; value: a };

@@ -43,2 +46,3 @@

const pattern2: Pattern<Input> = when((x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Input = x;

@@ -50,2 +54,3 @@ return true;

when((state) => {
const notNever: NotNever<typeof state> = true;
const inferenceCheck: State = state;

@@ -55,2 +60,3 @@ return !!state;

when((event) => {
const notNever: NotNever<typeof event> = true;
const inferenceCheck: Event = event;

@@ -70,2 +76,3 @@ return !!event;

data: when((d) => {
const notNever: NotNever<typeof d> = true;
const inferenceCheck: string = d;

@@ -91,2 +98,3 @@ return true;

x: when((x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string = x;

@@ -100,2 +108,3 @@ return true;

x: when((x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string = x;

@@ -110,2 +119,3 @@ return true;

x: when((x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string = x;

@@ -117,2 +127,3 @@ return true;

y: when((y) => {
const notNever: NotNever<typeof y> = true;
const inferenceCheck: number = y;

@@ -125,2 +136,3 @@ return true;

const pattern10: Pattern<string | number> = when((x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string | number = x;

@@ -130,2 +142,94 @@ return true;

});
it('should infer values correctly in handler', () => {
type Input = { type: string } | string;
match<Input, 'ok'>({ type: 'hello' })
.with(__, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Input = x;
return 'ok';
})
.with(__.string, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string = x;
return 'ok';
})
.with(
when((x) => true),
(x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Input = x;
return 'ok';
}
)
.with(not('hello'), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Input = x;
return 'ok';
})
.with(not(__.string), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.with(not(when((x) => true)), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Input = x;
return 'ok';
})
.with({ type: __ }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.with({ type: __.string }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.with({ type: when((x) => true) }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.with({ type: not('hello' as 'hello') }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.with({ type: not(__.string) }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.with({ type: not(when((x) => true)) }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.with(not({ type: when((x: string) => true) }), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Input = x;
return 'ok';
})
.with(not({ type: __.string }), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string = x;
return 'ok';
})
.run();
});
it('a union of object or primitive should be matched with a correct type inference', () => {
type Input = { type: string } | string;
match<Input, 'ok'>({ type: 'hello' })
.with({ type: __ }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { type: string } = x;
return 'ok';
})
.run();
});
});

@@ -139,2 +243,3 @@

.with(1, (v) => {
const notNever: NotNever<typeof v> = true;
const inferenceCheck: 1 = v;

@@ -144,2 +249,3 @@ return v * 2;

.with(2, (v) => {
const notNever: NotNever<typeof v> = true;
const inferenceCheck: 2 = v;

@@ -170,2 +276,3 @@ return v * v;

.with({ x: 1, y: 1, z: 1 }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Vector3 = x;

@@ -175,2 +282,3 @@ return 'vector3';

.with({ x: 2, y: 1 }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Vector2 = x;

@@ -180,2 +288,3 @@ return 'vector2';

.with({ x: 1 }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Vector1 = x;

@@ -200,2 +309,3 @@ return 'vector1';

.with({ kind: 'some' }, (o) => {
const notNever: NotNever<typeof o> = true;
const inferenceCheck: { kind: 'some'; value: string } = o;

@@ -217,2 +327,3 @@ return o.value;

.with([], (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: never[] = x;

@@ -222,2 +333,3 @@ return { kind: 'some', value: [{ id: 0, title: 'LOlol' }] };

.with([{ id: __.number, title: __.string }], (blogs) => {
const notNever: NotNever<typeof blogs> = true;
const inferenceCheck: { id: number; title: string }[] = blogs;

@@ -230,2 +342,3 @@ return {

.with(20, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: number = x;

@@ -270,2 +383,3 @@ return { kind: 'none' };

.with(['hello', 20], (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: [string, number] = x;

@@ -275,2 +389,3 @@ return `perfect match`;

.with(['hello', __], (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: [string, number] = x;

@@ -280,2 +395,3 @@ return `string match`;

.with([__, 20], (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: [string, number] = x;

@@ -285,2 +401,3 @@ return `number match`;

.with([__.string, __.number], (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: [string, number] = x;

@@ -290,2 +407,3 @@ return `not matching`;

.with([__, __], (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: [string, number] = x;

@@ -295,2 +413,3 @@ return `can't happen`;

.with(__, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: [string, number] = x;

@@ -385,2 +504,3 @@ return `can't happen`;

.with(new Set(['gab', 'yo']), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Set<string> = x;

@@ -390,2 +510,3 @@ return [true, true];

.with(new Set(['gab']), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Set<string> = x;

@@ -395,2 +516,3 @@ return [true, false];

.with(new Set(['yo']), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Set<string> = x;

@@ -400,2 +522,3 @@ return [false, true];

.with(__, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: Set<string | number> = x;

@@ -424,2 +547,41 @@ return [false, false];

describe('wildcards', () => {
it('should match String wildcards', () => {
const res = match<string | number | boolean, boolean>('')
.with(__.string, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string = x;
return true;
})
.otherwise(() => false)
.run();
expect(res).toEqual(true);
});
it('should match Number wildcards', () => {
const res = match<string | number | boolean, boolean>(2)
.with(__.number, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: number = x;
return true;
})
.otherwise(() => false)
.run();
expect(res).toEqual(true);
});
it('should match Boolean wildcards', () => {
const res = match<string | number | boolean, boolean>(true)
.with(__.boolean, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: boolean = x;
return true;
})
.otherwise(() => false)
.run();
expect(res).toEqual(true);
});
it('should match String, Number and Boolean wildcards', () => {

@@ -446,2 +608,41 @@ // Will be { id: number, title: string } | { errorMessage: string }

});
it('should infer correctly negated String wildcards', () => {
const res = match<string | number | boolean, boolean>('')
.with(not(__.string), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: number | boolean = x;
return true;
})
.otherwise(() => false)
.run();
expect(res).toEqual(false);
});
it('should infer correctly negated Number wildcards', () => {
const res = match<string | number | boolean, boolean>(2)
.with(not(__.number), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string | boolean = x;
return true;
})
.otherwise(() => false)
.run();
expect(res).toEqual(false);
});
it('should infer correctly negated Boolean wildcards', () => {
const res = match<string | number | boolean, boolean>(true)
.with(not(__.boolean), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: string | number = x;
return true;
})
.otherwise(() => false)
.run();
expect(res).toEqual(false);
});
});

@@ -505,2 +706,3 @@

(x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: 13 = x;

@@ -513,2 +715,3 @@ return true;

const notNever: NotNever<typeof res> = true;
const inferenceCheck: boolean = res;

@@ -534,2 +737,3 @@ });

(x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { status: 'success'; data: string } = x;

@@ -556,2 +760,3 @@ return true;

x: when((x): x is 20 => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: number = x;

@@ -563,2 +768,3 @@ return x === 20;

(vec) => {
const notNever: NotNever<typeof vec> = true;
const inferenceCheck: Vec3 = vec;

@@ -571,2 +777,3 @@ return vec.y > 2;

(x) => {
const notNever: NotNever<typeof vec> = true;
const inferenceCheck: Vec3 = vec;

@@ -588,2 +795,3 @@ return false;

.with(not(__.number), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: unknown = x;

@@ -593,2 +801,3 @@ return 'not a number';

.with(not(__.string), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: unknown = x;

@@ -608,2 +817,3 @@ return 'not a string';

.with({ y: __.number, x: not(__.string) }, (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: { x: number; y: number } = x;

@@ -626,2 +836,3 @@ return 'yes';

.with(not(one), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: 'two' = x;

@@ -631,2 +842,3 @@ return 'not 1';

.with(not(two), (x) => {
const notNever: NotNever<typeof x> = true;
const inferenceCheck: 'one' = x;

@@ -633,0 +845,0 @@ return 'not 2';

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