ts-pattern
Advanced tools
Comparing version 2.0.1-next.2 to 2.1.0
@@ -63,3 +63,3 @@ import type { IsAny, Cast, Values, Flatten, IsUnion, Slice, Drop, Iterator, Next } from './helpers'; | ||
] : a extends [infer a1, infer a2] ? [...FindUnions<a1, [...path, 0]>, ...FindUnions<a2, [...path, 1]>] : [] : a extends Set<any> ? [] : a extends Map<any, any> ? [] : a extends object ? Flatten<Values<{ | ||
[k in keyof Required<a>]: FindUnions<a[k], [...path, k]>; | ||
[k in keyof Required<a>]: FindUnions<NonNullable<a[k]>, [...path, k]>; | ||
}>> : []; | ||
@@ -66,0 +66,0 @@ export declare type Distribute<unions extends any[]> = unions extends [ |
{ | ||
"name": "ts-pattern", | ||
"version": "2.0.1-next.2", | ||
"version": "2.1.0", | ||
"description": "Typescript pattern matching library", | ||
@@ -12,3 +12,4 @@ "main": "lib/index.js", | ||
"test:types": "tsc --project tests/tsconfig.json", | ||
"test": "npm run test:types && npm run test:values" | ||
"test": "npm run test:types && npm run test:values", | ||
"perf": "tsc --project tests/tsconfig.json --noEmit --extendedDiagnostics" | ||
}, | ||
@@ -15,0 +16,0 @@ "files": [ |
140
README.md
@@ -14,3 +14,3 @@ <h1 align="center">ts-pattern</h1> | ||
```tsx | ||
```ts | ||
import { match } from 'ts-pattern'; | ||
@@ -27,9 +27,9 @@ | ||
let result: Result; | ||
const result: Result = ...; | ||
return match(result) | ||
.with({ type: 'ok', data: { type: 'text' } }, (res) => <p>{res.data.content}</p>) | ||
.with({ type: 'ok', data: { type: 'img' } }, (res) => <img src={res.data.src} />) | ||
.with({ type: 'error' }, (res) => <p>Oups! An error occured</p>) | ||
.otherwise(() => <p>everything else</p>); | ||
.with({ type: 'ok', data: { type: 'text' } }, (res) => `<p>${res.data.content}</p>`) | ||
.with({ type: 'ok', data: { type: 'img' } }, (res) => `<img src=${res.data.src} />`) | ||
.with({ type: 'error' }, (res) => `<p>Oups! An error occured</p>`) | ||
.otherwise(() => `<p>everything else</p>`); | ||
``` | ||
@@ -39,5 +39,6 @@ | ||
- Supports **every data structure** you use: objects, arrays, tuples, Sets, Maps, and all primitive types. | ||
- Works on **any data structure**: nested objects, arrays, tuples, Sets, Maps and all primitive types. | ||
- **Typesafe**, with great type inference. | ||
- Supports catch all (`__`) and type specific **wildcards**. | ||
- Optional **exhaustive matching**, enforcing that you are matching every possible case with `.exhaustive()`. | ||
- **Expressive syntax**, with catch-all and type specific **wildcards**: `__`. | ||
- Supports `when(<predicate>)` and `not(<pattern>)` patterns for complex cases. | ||
@@ -146,2 +147,4 @@ - Supports properties selection, via the `select(<name>)` function. | ||
match<[State, Event], State>([state, event]) | ||
.exhaustive() | ||
.with([{ status: 'loading' }, { type: 'success' }], ([, event]) => ({ | ||
@@ -165,14 +168,5 @@ status: 'success', | ||
.with( | ||
[ | ||
{ | ||
status: 'loading', | ||
startTime: when((startTime) => Date.now() > startTime + 1000), | ||
}, | ||
{ type: 'cancel' }, | ||
], | ||
() => ({ | ||
status: 'idle', | ||
}) | ||
) | ||
.with([{ status: 'loading' }, { type: 'cancel' }], () => ({ | ||
status: 'idle', | ||
})) | ||
@@ -204,2 +198,13 @@ .with(__, () => state) | ||
### .exhaustive() | ||
`.exhaustive()` enables **exhaustive matching**, making sure we don't forget | ||
any possible case in our input data. This extra type safety is very nice | ||
because forgetting a case is an easy mistake to make, especially in an | ||
evolving code-base. | ||
Note that exhaustive pattern matching is **optional**. It comes with the trade-off | ||
of **disabling guard functions** (`when(...)`) and having **longer compilation times**. | ||
If you are using `.otherwise()`, you probably don't need to use `.exhaustive()`. | ||
### .with(pattern, handler) | ||
@@ -260,24 +265,2 @@ | ||
### when(predicate) | ||
The `when` function enables you to **add a guard** to your pattern. | ||
Your pattern will not match **unless your predicate returns `true`**. | ||
It might be handy if you need to make a dynamic checks on | ||
your data structure. | ||
```ts | ||
.with( | ||
[ | ||
{ | ||
status: 'loading', | ||
startTime: when((startTime) => Date.now() > startTime + 1000), | ||
}, | ||
{ type: 'cancel' }, | ||
], | ||
() => ({ | ||
status: 'idle', | ||
}) | ||
) | ||
``` | ||
### the `__` wildcard | ||
@@ -314,2 +297,57 @@ | ||
### Guard functions | ||
Sometimes, we need to make sure our input data respects a condition | ||
that can't be expressed by a pattern. Imagine if we wanted to check that a number | ||
is positive for instance. In this case, we can use **guard functions**: | ||
functions taking some data and returning a `boolean`. | ||
With `ts-pattern` you have two options to use a guard function: | ||
- use `when(<guard function>)` inside your pattern | ||
- pass it as second parameter to `.with(...)` | ||
**Note**: to use this feature, you will need to **disable exhaustive matching** | ||
by removing `.exhaustive()` if you were using it. That's because with guard functions, | ||
there is no way to know if the pattern is going to match or not at compile time, | ||
making exhaustive matching impossible. | ||
#### when(predicate) | ||
The `when` function lets you **add a guard** to your pattern. | ||
Your pattern will not match **unless your predicate (guard) function returns `true`**. | ||
It might be handy if you need to make a dynamic checks on | ||
your data structure. | ||
```ts | ||
.with( | ||
[ | ||
{ | ||
status: 'loading', | ||
startTime: when((startTime) => Date.now() > startTime + 1000), | ||
}, | ||
{ type: 'cancel' }, | ||
], | ||
() => ({ | ||
status: 'idle', | ||
}) | ||
) | ||
``` | ||
#### Passing a guard function to `.with(...)` | ||
`.with` optionally accepts up to 3 guard functions parameters between | ||
the `pattern` and the `handler` callback: | ||
```ts | ||
.with( | ||
[{ status: 'loading' },{ type: 'cancel' }], | ||
([state, event]) => Date.now() > state.startTime + 1000, | ||
// you can add up to 2 other guard functions here | ||
() => ({ | ||
status: 'idle' | ||
}) | ||
) | ||
``` | ||
## API Reference | ||
@@ -400,2 +438,19 @@ | ||
### .exhaustive | ||
```ts | ||
match(...) | ||
.exhaustive() | ||
.with(...) | ||
``` | ||
Enable exhaustive pattern matching, making sure at compile time that | ||
all possible cases are handled. | ||
#### Signature | ||
```ts | ||
function exhaustive(): ExhaustiveMatch<TInput, IOutput>; | ||
``` | ||
### .otherwise | ||
@@ -815,3 +870,4 @@ | ||
- It provides a "catch all" pattern: `__`. | ||
- It supports exhaustive matching with `.exhaustive()`. | ||
- It supports deep selection with the `select()` function. | ||
- Its type inference works on deeper patterns and is well tested. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
55814
0
864