> [!note] A common type design pattern in [[TypeScript]]. #design-pattern
```typescript
type UserId = number & { __brand: "foo" }
```
This is where the nominal and structural subtyping are in a conflict.
Passing primitives (`string` or `int`) around is not recommended, as it is easy to mistake one for another. Especially concerning entities like primary key types, one may want to define a type that doesn't interoperate with other types. i.e. `getUser(userId: number)` and `getPost(postId: number)` want to have distinct types for ids, even if they happen to be numbers.
There are few ways to do this;
- define one's own structure - say `{ type: "User", id: number }`. However, this has overhead as now one's passing an object instead of a `number`.
Branded types are a "hack" around this:
- Branded types aren't "real"; manifestations of the branded types doesn't exist; in fact it may never exist as one cannot subclass `string` nor `number` in JavaScript.
- Branded types are always created via casting. ex: `const id:UserId = 3 as UserId`.
- one can always pass in the branded types where the primitive version is expected.
- one cannot pass a primitive when a function expects a branded type, unless an explicit casting is performed.
# Usage
```typescript
type UserId = number & { __brand: "foo" }
type User = {
id: UserId
related: UserId
}
async function getUser(id: UserId): User { ... }
getUser(3) // does not compile
const id = 42 as UserId;
const u1 = await getUser(id) // does compile.
const u2 = await getUser(u1.related);
```
# Literature
- https://egghead.io/blog/using-branded-types-in-typescript