# ts-union-tools

> minimal utilities to work with union types and tagged unions (a.k.a. discriminated unions) in TypeScript

Latest version **0.0.1** (published 2020-08-23) · ISC license · 0 weekly downloads

## Install

```sh
npm install ts-union-tools
pnpm add ts-union-tools
yarn add ts-union-tools
bun add ts-union-tools
```

## Health

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

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.1 |
| Published | 2020-08-23 |
| First published | 2020-08-23 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 47.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 9 |
| Author | naruaway |
| Maintainers | naruaway |
| Keywords | TypeScript, tagged unions, discriminated unions, pattern matching |

## Links

- npm: https://www.npmjs.com/package/ts-union-tools
- Repository: https://github.com/naruaway/ts-union-tools
- Issues: https://github.com/naruaway/ts-union-tools/issues
- npm.io page: https://npm.io/package/ts-union-tools

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 0.0.1 (latest) — 2020-08-23
- 0.0.0 — 2020-08-23

## README

# ts-union-tools

![Overview](https://user-images.githubusercontent.com/2931577/90972783-0363a980-e557-11ea-8996-1a36182e0d2f.png)
ts-union-tools is a set of minimal utilities to work with union types and tagged unions (a.k.a. discriminated unions) in TypeScript.
The main API is pattern matching utility functions called `match` and `matchOn` to do type-safe pattern-match against unions and tagged unions elegantly without `if-else` or `switch`.
It also provides useful type utilities to work with tagged union types.

## Features

- No opaque objects / classes. It just provides simple utility functions and type utilities to work seamlessly with existing union types in _your codebase_ such as `type Person = {role: 'Dev', language: string} | {role: 'UX', tool: string} | 'Sales'`
- Each utility function is overloaded with data-last curried version, which can be nicely used with other functional composition utilities like [flow in Lodash](https://lodash.com/docs/4.17.15#flow) or [pipe in Ramda](https://ramdajs.com/docs/#pipe)

## How to use

Make sure you run `npm install ts-union-tools` to make it available in your project.

### `matchOn` function for pattern-match against tagged unions

`matchOn` does pattern-match against tagged-unions, even mixed with raw literals like `'Sales'` in the following example.
You can use any name (e.g. `kind`, `type` and `role`) for the name of the "tag" in tagged unions by specifying the first argument of `matchOn`.

```typescript
import { matchOn } from 'ts-union-tools'

type Person =
  | { role: 'Dev'; language: string }
  | { role: 'UX'; tool: string }
  | 'Sales'
  | 'PM'

const person: Person =
  Math.random() > 0.5
    ? {
        role: 'Dev',
        language: 'TypeScript',
      }
    : Math.random() > 0.5
    ? {
        role: 'UX',
        tool: 'Photoshop',
      }
    : Math.random() > 0.5
    ? 'Sales'
    : 'PM'

const message = matchOn('role', person, {
  Dev: (dev) => `I am a dev using ${dev.language}`,
  UX: (ux) => `I am a UI/UX designer using ${ux.tool}`,
  Sales: () => 'I am a salesperson',
  // "_" (underscore) can be used as catch-all case
  _: () => 'I have some other role',
})

console.log(message)
```

### `match` function for pattern-match against simple unions

When a union type does not contain "tagged union", it does not make sense to specify the name of "tag" (e.g. `kind`, `type` and `role`)
In that case, we can use a simpler function, `match`.

```typescript
import { match } from 'ts-union-tools'

type Person = 'Dev' | 'UX' | 'Sales' | 'PM'

const person: Person =
  Math.random() > 0.5
    ? 'Dev'
    : Math.random() > 0.5
    ? 'UX'
    : Math.random() > 0.5
    ? 'Sales'
    : 'PM'

const message = match(person, {
  Dev: () => 'I am a dev',
  UX: () => 'I am a UI/UX designer',
  Sales: () => 'I am a salesperson',
  PM: () => 'I have some other role',
})

console.log(message)
```

### Type utilities (to be documented)

- `GetUnionTags<UnionType>`
- `TaggedUnionExtract<UnionType>`
- `TaggedUnionExclude<UnionType>`

## Why not just use `switch` or `if-else`?

TBD

## License

See [LICENSE](./LICENSE)

## Contributions

See [CONTRIBUTING](./CONTRIBUTING.md)

---
_Source: https://npm.io/package/ts-union-tools · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
