An open API service indexing awesome lists of open source software.

https://github.com/hasparus/nom-ts

🤓 TypeScript nominal-typing helpers
https://github.com/hasparus/nom-ts

Last synced: 5 months ago
JSON representation

🤓 TypeScript nominal-typing helpers

Awesome Lists containing this project

README

          

# nom-ts

TypeScript helpers for nominal typing

---

# Problem

- 😀 Nominal types are [pretty useful](https://github.com/Microsoft/TypeScript/blob/69abe49930761aea92dc564f9b6a5db74d6e1be9/src/compiler/types.ts#L1183-L1192).
- 😞 TypeScript doesn't support nominal types ([yet?](https://github.com/microsoft/TypeScript/wiki/Roadmap/69ede9ef95de7bf8764a2f2fa3c3d4c441cc828d#future)).

Great! This is easy to fix right?
The simple trick below solves the problem.

```ts
declare const __brand: unique symbol;

declare const __type: unique symbol;

interface __Brand {
[__brand]: S;
[__type]: T;
}

export type Brand = T & __Brand;
```

But then we encounter some more happy little problems.

```ts
type PlayerId = Brand;
type PlayerScores = Record;

const myId = 1337 as PlayerId;
const scores: PlayerScores = { [myId]: 9001 };

// Element implicitly has an 'any' type because expression
// of type 'Brand' can't be used to
// index type 'Record, number>'.
// ts(7053)
const myScore = scores[myId];
```

**nom-ts aims to address these problems.**

# Goals

- 🦅 no dependencies
- 🦥 all branded types in nom-ts are assignable to their underlying type
without any additional syntax

# The rest of the code

```ts
interface __Flavor {
[__brand]?: S;
/**
* Intersection is distributive over union, but we don't want to "lose" information about T.
* `__type?: T` will be useful for Unbrand.
*/
[__type]?: T;
}

export type Flavor = T & __Flavor;

export type Unbrand = T extends Flavor ? X : T;

export const Unbrand = (x: T) => x as Unbrand;

export type Dict = Record, V>;
```

# Links

- https://github.com/Microsoft/TypeScript/issues/202
- https://basarat.gitbooks.io/typescript/docs/tips/nominalTyping.html
- "Brand" name is taken from
https://michalzalecki.com/nominal-typing-in-typescript/
- "Flavor" name is taken from
https://spin.atomicobject.com/2018/01/15/typescript-flexible-nominal-typing/
- https://github.com/gcanti/newtype-ts

----

#### Credits

This project was bootstrapped with [TSDX](https://github.com/jaredpalmer/tsdx).