Brand 타입은 런타임에는 동일하지만, 컴파일 타임에서만 서로 다른 타입으로 취급되게 만드는 기법
Typescript는 구조적 타이핑(structural typing)이기 떄문에, 모양이 같으면 같은 타입으로 취급해버리는 문제가 있음
type UserId = string;
type OrderId = string;
const userId: UserId = 'u1';
const orderId: OrderID = 'o1';
// 컴파일 에러 없음
sendOrder(userId);
이걸 컴파일 타임에 막고 싶을 때 brand 타입을 사용한다.
string은 그냥 string특히 SDK / 도메인 코드 / 금융, 결제 / POS에서 중요
가장 흔한 패턴
type Brand<K, T> = K & { __brand: T };
type UserId = Brand<string, 'UserId'>;
type OrderId = Brand<string, 'OrderId'>;
사용
const userId = 'u1' as UserId;
const orderId = 'o1' as OrderId;
// 컴파일 에러
sendOrder(userId);
// 정상
sendOrder(orderId);
맞는말 + 틀린 말
as를 남용하면 의미 없음권장 패턴 : 생성함수
function createUserId(value: string): UserId {
// 여기서 검증 가능
return value as UserId;
}
const userId = createUserId('u1');
// 이후에는 타입 안전
좀더 안전한 패턴 (unique symbol)
declare const userIdBrand: unique symbol;
type UserId = string & { [userIdBrand]: void };
장점