타입스크립트의 Brand 타입을 활용하면 좀 더 엄격한 프로그래밍을 할 수 있다.
```typescript
declare const brand: unique symbol;
type Brand<T, TBrand> = T & { [brand]: TBrand };
type UserId = Brand<string, "UserId">;
const userId = "1" as UserId;
```
Brand 타입은 위와 같이 정의가 된다. 총 2개의 타입 인자를 넘겨야 하는데 첫번째 타입 인자는 실제 값의 타입을 넘겨주고, 두번째는 이 Brand 타입의 이름을 넘겨준다. `const userId = "1" as UserId;` 코드를 보면 `UserId`는 `string` 타입을 받기 위해 첫번째 인자로 `string`을 넘겨주었고 이 타입의 이름을 위해 두번째 인자에는 `UserId`를 넘겨주었다.
여기서 `{[brand]: TBrand}`에 대한 부연 설명을 하면,
`unique symbol`은 TypeScript에서 고유한 symbol을 만들 때 사용하는 키워드이고, `TBrand`가 변경되면 (즉, 다른 고유 심볼을 가리키게 되면) 생성된 `Brand<T, TBrand>` 유형도 고유하게 변경된다.
예제를 통해 어떻게 엄격한 프로그래밍이 가능한지 확인해보겠다.
```typescript
type UserId = Brand<string, "UserId">;
type PostId = Brand<string, "PostId">;
interface User {
id: string;
name: string;
}
interface Post {
id: string;
title: string;
content: string;
}
function getPost(id: string) {
// do something
}
const userId = "1"
getPost(userId)
```
위 예제에서 `getPost`는 `string` 타입의 `id`를 받는다. `User`, `Post` 모두 `id`의 타입이 string 이므로 `getPost`를 호출할 때 실수로 `userId`를 넘겨도 타입에러가 발생하지 않는다.
이런 실수를 방지하기 위해 Brand 타입을 사용할 수 있다.
```typescript
function getPost(id: PostId) {
// do something
}
const userId = "1"
// Error 🚨
getPost(userId)
```
`getPost`의 매개 변수를 `PostId` 타입으로 지정해주니까 `getPost`에 string 값을 넘겨주었을 때 타입 에러가 발생하게 되고 프로그래머가 잘못된 것을 넘겨주었다고 인지할 수 있다.
---
참조 강의: https://inf.run/FVDi