## Ts Pattern
%% generate tags start %%
#software-engineering
%% generate tags end %%
#software-engineering/typescript
Write **better** and **safer conditions**. Pattern matching lets you express complex conditions in a single, compact expression. Your code becomes **shorter** and **more readable**. Exhaustiveness checking ensures you haven't forgotten **any possible case**.

### Why Do We Need This?
imagine you have a code like this
```ts
type Data =
| { type: 'text'; content: string }
| { type: 'img'; src: string };
type Result =
| { type: 'ok'; data: Data }
| { type: 'error'; error: Error };
const result: Result = ...;
const html = ...; // how can I do this ???
```
you want to assign different html base on the result type and data type. Normally in js, you will use if else clause to do. But there is several problems.
1. you cannot start with `const html` because you are assigning the value inside the if else clause. You can only use `let html` but that is not good because now the value is not a const and can be changed.
2. since `data` is a property nested in `result`, you will need two level of if else clause. This will create if else hell and that is not good.
3. you cannot if the if else clause is exhaustive because you are doing the pattern matching multiple layer of scope.
We want a solution such that:
1. no if else hell, no multiple layer, single level, easy to read
2. typesafe and exhaustive
we have `ts-pattern` 🔥
```ts
import { match, P } from 'ts-pattern';
const html = match(result)
.with({ type: 'error' }, () => `<p>Oups! An error occured</p>`)
.with({ type: 'ok', data: { type: 'text' } }, (res) => `<p>${res.data.content}</p>`)
.with({ type: 'ok', data: { type: 'img', src: P.select() } }, (src) => `<img src=${src} />`)
.exhaustive();
```
### How to Use?
```
pnpm add ts-pattern
```
then you go to check out `match`, `returnType`, `with`, `exhaustive` because you will use them most!
## Effect ts match
[Effect-TS/match: Functional pattern matching with the full power of TypeScript (github.com)](https://github.com/Effect-TS/match)
```ts
import * as Match from "@effect/match"
import { pipe } from "@effect/data/Function"
const match = pipe(
Match.type<{ a: number } | { b: string }>(),
Match.when({ a: Match.number }, (_) => _.a),
Match.when({ b: Match.string }, (_) => _.b),
Match.exhaustive,
)
console.log(match({ a: 0 })) // 0
console.log(match({ b: "hello" })) // "hello"
```