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 5.0.3 to 5.0.4

2

dist/types/Pattern.d.ts

@@ -62,3 +62,3 @@ import type * as symbols from '../internals/symbols.js';

type KnownPattern<a> = KnownPatternInternal<a>;
type KnownPatternInternal<a, objs = Exclude<a, Primitives | Map<any, any> | Set<any> | readonly any[]>, arrays = Extract<a, readonly any[]>, primitives = Exclude<a, object>> = primitives | PatternMatcher<a> | ([objs] extends [never] ? never : ObjectPattern<Readonly<MergeUnion<objs>>>) | ([arrays] extends [never] ? never : ArrayPattern<arrays>);
type KnownPatternInternal<a, objs = Exclude<a, Primitives | Map<any, any> | Set<any> | readonly any[]>, arrays = Extract<a, readonly any[]>, primitives = Extract<a, Primitives>> = primitives | PatternMatcher<a> | ([objs] extends [never] ? never : ObjectPattern<Readonly<MergeUnion<objs>>>) | ([arrays] extends [never] ? never : ArrayPattern<arrays>);
type ObjectPattern<a> = {

@@ -65,0 +65,0 @@ readonly [k in keyof a]?: Pattern<a[k]>;

{
"name": "ts-pattern",
"version": "5.0.3",
"version": "5.0.4",
"description": " The exhaustive Pattern Matching library for TypeScript.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -61,5 +61,5 @@ <h1 align="center">TS-Pattern</h1>

[Pattern Matching](https://stackoverflow.com/questions/2502354/what-is-pattern-matching-in-functional-languages) is a code-branching technique coming from functional programming languages, which lets you scrutinize the structure of values in a declarative way. It has proven itself to be less verbose and more powerful than imperative alternatives (if/else/switch statements), especially when branching on complex data structures or on several values.
[Pattern Matching](https://stackoverflow.com/questions/2502354/what-is-pattern-matching-in-functional-languages) is a code-branching technique coming from functional programming languages that's more powerful and often less verbose than imperative alternatives (if/else/switch statements), especially for complex conditions.
Pattern Matching is implemented in Haskell, Rust, Swift, Elixir 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. Luckily, 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 Haskell, Rust, Swift, Elixir, and many other languages. There is [a tc39 proposal](https://github.com/tc39/proposal-pattern-matching) to add Pattern Matching to EcmaScript, but it is still in stage 1 and isn't likely to land before several years. Luckily, pattern matching can be implemented in userland. `ts-pattern` Provides a typesafe pattern matching implementation that you can start using today.

@@ -144,4 +144,3 @@ Read the introduction blog post: [Bringing Pattern Matching to TypeScript 🎨 Introducing TS-Pattern](https://dev.to/gvergnaud/bringing-pattern-matching-to-typescript-introducing-ts-pattern-v3-0-o1k)

As an example, we are going to create a state reducer for a
frontend application fetching some data using an HTTP request.
As an example, let's create a state reducer for a frontend application that fetches some data.

@@ -175,8 +174,5 @@ ### Example: a state reducer with ts-pattern

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.
To avoid unwanted state changes that could lead to bugs, we want our state reducer function to branch on **both the state and the event**, and return a new state.
This is a case where `match` really shines. Instead of writing nested
switch statements, we can do that in a very expressive way:
This is a case where `match` really shines. Instead of writing nested switch statements, we can use pattern matching to simultaneously check the state and the event object:

@@ -187,24 +183,16 @@ <!-- prettier-ignore -->

const reducer = (state: State, event: Event): State =>
match<[State, Event], State>([state, event])
const reducer = (state: State, event: Event) =>
match([state, event])
.returnType<State>()
.with(
[{ status: 'loading' }, { type: 'success' }],
([, event]) => ({
status: 'success',
data: event.data,
})
([_, event]) => ({ status: 'success', data: event.data })
)
.with(
[{ status: 'loading' }, { type: 'error', error: P.select() }],
(error) => ({
status: 'error',
error,
})
(error) => ({ status: 'error', error })
)
.with(
[{ status: P.not('loading') }, { type: 'fetch' }],
() => ({
status: 'loading',
startTime: Date.now(),
})
() => ({ status: 'loading', startTime: Date.now() })
)

@@ -219,5 +207,3 @@ .with(

],
() => ({
status: 'idle',
})
() => ({ status: 'idle' })
)

@@ -228,3 +214,3 @@ .with(P._, () => state)

**Let's go through this bit by bit:**
There's a lot going on, so **let's go through this code bit by bit:**

@@ -235,15 +221,19 @@ ### match(value)

<!-- prettier-ignore -->
```ts
match<[State, Event], State>([state, event]);
match([state, event])
```
Here we wrap the state and the event objects in an array and we explicitly
specify the type `[State, Event]` to make sure it is interpreted as
a [Tuple](#tuples-arrays) by TypeScript, so we
can match on each value separately.
It's also possible to specify the input and output type explicitly with `match<Input, Output>(...)`, but this is usually unnecessary, as TS-Pattern is able to infer them.
Most of the time, you don't need to specify the type of input
and output with `match<Input, Output>(...)` because `match` is able to
infer both of these types.
### .returnType\<OutputType\>()
`.returnType` is an optional method that you can call if you want to force all following code-branches to return a value of a specific type. It takes a single type parameter, provided between `<AngleBrackets>`.
```ts
.returnType<State>()
```
Here, we use this method to make sure all branches return a valid `State` object.
### .with(pattern, handler)

@@ -265,7 +255,5 @@

The first argument is the **pattern**: the **shape of value**
you expect for this branch.
The first argument is the **pattern**: the **shape of value** you expect for this branch.
The second argument is the **handler function**: the code **branch** that will be called if
the input value matches the pattern.
The second argument is the **handler function**: the code **branch** that will be called if the input value matches the pattern.

@@ -284,6 +272,3 @@ The handler function takes the input value as first parameter with its type **narrowed down** to what the pattern matches.

],
(error) => ({
status: 'error',
error,
})
(error) => ({ status: 'error', error })
)

@@ -332,5 +317,3 @@ ```

[{ status: P.not('loading') }, { type: 'fetch' }],
() => ({
status: 'loading',
})
() => ({ status: 'loading' })
)

@@ -341,7 +324,7 @@ ```

Sometimes, we need to make sure our input value respects a condition that can't be expressed by a pattern. For example, imagine you need to check if a number is positive. In these cases, we can use **guard functions**: functions taking a value and returning a `boolean`.
Sometimes, we need to make sure our input value respects a condition that can't be expressed by a pattern. For example, imagine you need to check that a number is positive. In these cases, we can use **guard functions**: functions taking a value and returning a `boolean`.
With `ts-pattern` there are two options to use a guard function:
With TS-Pattern, there are two ways to use a guard function:
- use `P.when(<guard function>)` inside your pattern
- use `P.when(<guard function>)` inside one of your patterns
- pass it as second parameter to `.with(...)`

@@ -360,5 +343,3 @@

],
() => ({
status: 'idle',
})
() => ({ status: 'idle' })
)

@@ -376,5 +357,3 @@ ```

([state, event]) => state.startTime + 2000 < Date.now(),
() => ({
status: 'idle'
})
() => ({ status: 'idle' })
)

@@ -408,5 +387,5 @@ ```

Note that exhaustive pattern matching is **optional**. It comes with the trade-off of having **longer compilation times** because the type checker has more work to do.
Note that exhaustive pattern matching is **optional**. It comes with the trade-off of having slightly **longer compilation times** because the type checker has more work to do.
Alternatively you can use `.otherwise()`, which takes an handler function returning a default value. `.otherwise(handler)` is equivalent to `.with(P._, handler).exhaustive()`.
Alternatively, you can use `.otherwise()`, which takes an handler function returning a default value. `.otherwise(handler)` is equivalent to `.with(P._, handler).exhaustive()`.

@@ -417,10 +396,2 @@ ```ts

If you don't want to use `.exhaustive()` and also don't want to provide a default value with `.otherwise()`, you can use `.run()` instead:
```ts
.run();
```
It's just like `.exhaustive()`, but it's **unsafe** and might throw runtime error if no branch matches your input value.
### Matching several patterns

@@ -598,3 +569,3 @@

```ts
function exhaustive(): IOutput;
function exhaustive(): TOutput;
```

@@ -658,3 +629,3 @@

Runs the pattern-matching expression and returns its result. It throws an error at run time if no match was found, same as `exhaustive()`. However, unlike `.exhaustive()`, exhaustiveness is not checked at compile time, meaning the type checker will not verify that all possible cases are covered.
returns the result of the pattern-matching expression, or **throws** if no pattern matched the input. `.run()` is similar to `.exhaustive()`, but is **unsafe** because exhaustiveness is not checked at compile time, so you have no guarantees that all cases are indeed covered. Use at your own risks.

@@ -661,0 +632,0 @@ #### Signature

Sorry, the diff of this file is not supported yet

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