# @kklm/pattern-match

> Pattern matching is a feature built in into many programming languages. Sadly it's not included in JavaScript nor TypeScript. It's like a `switch` statement on steroids, that lets you write a more declarative code.

Latest version **1.0.2** (published 2022-12-30) · 0 weekly downloads

## Install

```sh
npm install @kklm/pattern-match
pnpm add @kklm/pattern-match
yarn add @kklm/pattern-match
bun add @kklm/pattern-match
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.2 |
| Published | 2022-12-30 |
| First published | 2022-12-06 |
| Weekly downloads | 0 |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 30.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | redshift |

## Links

- npm: https://www.npmjs.com/package/@kklm/pattern-match
- npm.io page: https://npm.io/package/@kklm/pattern-match

## Recent versions

- 1.0.2 (latest) — 2022-12-30
- 1.0.1 — 2022-12-30
- 1.0.0 — 2022-12-30
- 0.0.8 — 2022-12-20
- 0.0.7 — 2022-12-20
- 0.0.6 — 2022-12-19
- 0.0.5 — 2022-12-06

## README

# Typescript Pattern Matching

Pattern matching is a feature built in into many programming languages. Sadly it's not included in JavaScript nor TypeScript. It's like a `switch` statement on steroids, that lets you write a more declarative code.

This library aims to implement a pattern matching system that works well with other aspects of TS. It uses Builder Pattern to get all the cases and evaluate them.
The default case is mandatory.

## Installation

Install it using npm (or yarn).

```bash
npm install @kklm/pattern-match
```

It can be imported then in your *.ts files.

```typescript

import match, { AnyNumber, AnyString } from '@kklm/pattern-match'

// (...)

// with default matcher
match<any, string>(x)
  .case(AnyNumber, () => '...')
  .case(AnyString, () => '...')
  .default(() => '...')

// with unsafe unwrap
match<any, string>(x)
  .case(AnyNumber, () => '...')
  .case(AnyString, () => '...')
  .unwrap()

// convert to Option monad
match<any, string>(x)
  .case(AnyNumber, () => '...')
  .case(AnyString, () => '...')
  .toOption()

// convert to ResultMonad
match<any, string>(x)
  .case(AnyNumber, () => '...')
  .case(AnyString, () => '...')
  .toResult()
```

## Comparison with other languages
### Scala
```scala
import scala.util.Random

val x: Int = Random.nextInt(10)

x match {
  case 0 => "zero"
  case 1 => "one"
  case 2 => "two"
  case _ => "other"
}
```
### Elm
```elm
patternMatching : Int -> String
patternMatching x =
  case x of
    0 -> "zero"
    1 -> "one"
    2 -> "two"
    _ -> "other"
```
### Typescript with this library
```typescript
const x = Math.floor(Math.random() * 10);

match(x)
  .case(0, () => 'zero')
  .case(1, () => 'one')
  .case(2, () => 'two')
  .default(() => 'other')
```

## Examples

### Simple value based pattern matching
```typescript
const result = match(5)
  .case(1, () => 'one')
  .case(3, () => 'three')
  .case(5, () => 'five')
  .default(x => `The value is ${x}`)
  
result // 'five'
```

### Partial pattern matching on objects
```typescript
const result = match(anObject)
  .case({ loading: true }, () => 'Loading...')
  .case({ data: true }, () => 'Data received')
  .default(() => 'Default state')
```

### Partial pattern matching with Any matchers
```typescript
const result = match(anObject)
  .case({ loading: true }, () => 'Loading...')
  .case({ data: AnyObject }, () => 'Data received')
  .case({ error: AnyObject }, () => 'Error!')
  .default(() => 'Default state')
```

### Typesafe JSON parsing

When parsing JSON strings we do not know if the result will be correctly typed.

```typescript
interface User {
  name: string
  age: number
}

const jsonString = '{ "definetly": "not an user" }'
const user = JSON.parse(jsonString) as User

user.name // runtime boom
```

```typescript
interface User {
  name: string
  age: number
}

const jsonString = '{ "definetly": "not an user" }'

const user = match<unknown, User>(JSON.parse(jsonString))
  .case({ name: AnyString, age: AnyNumber }, (user: unknown) => user as User)
  .toResult()

user.match({
  Ok: user => "user parsed correctly",
  Err: _err => "handle parse error"
})
```

---
_Source: https://npm.io/package/@kklm/pattern-match · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
