
타입스크립트를 공부하다 보면 단순한 문법을 넘어서 트릭처럼 느껴지는 문법 패턴들을 만나게 됩니다.
이 글에서는 그중에서도 유니온 추출 / 매핑 후 값 유니온화 / 튜플 원소 타입 뽑기 같은 핵심 패턴을 정리합니다.
T[number] → 배열/튜플 원소 타입 유니온T에 [number]를 붙이면, 해당 배열의 모든 원소 타입을 유니온으로 추출합니다.type Roles = ["guest", "user", "admin"];
type Union = Roles[number];
// "guest" | "user" | "admin"
👉 튜플이든 배열이든, [number]는 “이 타입에서 나올 수 있는 모든 값들의 합집합”을 의미합니다.
즉, 런타임 반복이 아니라 타입 레벨 유니온 추출이에요.
Obj[keyof Obj] → 객체 value 타입 유니온keyof Obj는 키들의 유니온.Obj[keyof Obj]를 하면, 그 키들에 해당하는 모든 value 타입을 유니온으로 가져옵니다.type Obj = {
a: number;
b: string;
};
type Values = Obj[keyof Obj];
// number | string
👉 이 패턴은 “객체의 모든 value 타입을 유니온으로 만들고 싶을 때” 사용합니다.
{ [P in keyof T]: ... }[keyof T] → 매핑 후 값 유니온 뽑기[keyof T]로 인덱싱하면, 생성된 객체의 value들을 유니온으로 모아 추출합니다.type Obj = { a: 1; b: 2; c: 3 };
type PickEven<T> = {
[P in keyof T]: T[P] extends 2 ? P : never
}[keyof T];
type Result = PickEven<Obj>;
// "b"
👉 ...}[keyof T] 트릭은 매핑 타입 결과를 다시 유니온으로 만드는 핵심 패턴입니다.
이제 위의 트릭을 합쳐서, 특정 역할(Role)에 따라 접근 가능한 경로를 타입으로 구하는 문제를 풀어보겠습니다.
"guest" | "user" | "admin"export type Role = "guest" | "user" | "admin";
export type RouteMap = {
"/": { roles: ["guest", "user", "admin"] };
"/login": { roles: ["guest"] };
"/dashboard": { roles: ["user", "admin"] };
"/settings": { roles: ["admin"] };
};
export type AccessibleRoutes<R extends Role> = never // 초기 상태
// AccessibleRoutes<R> 기대값
// ----------------------------
type G = AccessibleRoutes<"guest">;
type G_Expected = "/" | "/login";
type _g = Expect<Equal<G, G_Expected>>;
type U = AccessibleRoutes<"user">;
type U_Expected = "/" | "/dashboard";
type _u = Expect<Equal<U, U_Expected>>;
type A = AccessibleRoutes<"admin">;
type A_Expected = "/" | "/dashboard" | "/settings" | "/login";
type _a = Expect<Equal<A, A_Expected>>;
정답
// 1. 특정 path의 roles 유니온 추출
type RouteRoles<P extends keyof RouteMap> = RouteMap[P]["roles"][number];
// 2. 매핑 타입 + 조건부 타입 → 접근 가능한 path 필터링
export type AccessibleRoutes<R extends Role> = {
[P in keyof RouteMap]: R extends RouteRoles<P> ? P : never
}[keyof RouteMap];
AccessibleRoutes<"guest"> → "/" | "/login" AccessibleRoutes<"user"> → "/" | "/dashboard" AccessibleRoutes<"admin"> → "/" | "/dashboard" | "/settings"T[number]: 배열/튜플 원소 타입을 유니온으로 추출하는 패턴 Obj[keyof Obj]: 객체의 value 타입들을 유니온으로 추출하는 패턴 { [P in keyof T]: ... }[keyof T]: 매핑 타입 후 값을 다시 유니온으로 모으는 패턴