typeof
→ 이미 존재하는 값의 모양을 그대로 타입으로 쓰고 싶을 때keyof
→ 어떤 타입이 가진 속성 이름 목록이 필요할 때keyof typeof obj
→ 이 객체에 실제로 존재하는 key 이름만 허용하고 싶을 때
아래 예시들만 이해되면 실무에서 바로 써먹을 수 있다.
1. typeof – 값에서 타입 뽑아 쓰기
CONFIG 같은 설정 객체를 하나 만들어 놨는데,
이 구조와 완전히 똑같은 타입이 필요하다
const CONFIG = {
retryCount: 3,
timeoutMs: 5000,
baseUrl: "https://api.example.com",
}
// CONFIG와 같은 모양의 타입 만들기
type Config = typeof CONFIG
Config는 아래와 같은 타입으로 인식된다
type Config = {
retryCount: number
timeoutMs: number
baseUrl: string
}
왜 이렇게 쓰냐?
이유 두 가지.
- 타입을 두 번 안 적어도 된다.
- 객체 한 번, 타입 한 번 이렇게 중복 정의할 필요 없음
- 구조가 바뀌면 타입도 자동으로 같이 바뀐다.
- CONFIG에 필드를 추가하거나 이름을 바꾸면
Config타입도 거기에 맞춰서 자동으로 변경
- CONFIG에 필드를 추가하거나 이름을 바꾸면
느낌만 잡으면 된다.
typeof = "이 값처럼 생긴 타입 하나 만들어 줘"
2. keyof – 타입에서 키 이름만 뽑기
이번엔 반대 방향이다.
타입 → 키 이름.
type User = {
id: number
name: string
email: string
}
// User가 가진 key 이름들을 뽑아서 유니온 타입으로 만들기
type UserKey = keyof User
// "id" | "name" | "email"
어디에 쓰면 좋냐?
예를 들어, User의 key만 받을 수 있는 함수를 만들고 싶을 때.
type User = {
id: number
name: string
email: string
}
type UserKey = keyof User
function getUserField(user: User, key: UserKey) {
return user[key]
}
getUserField({ id: 1, name: "Lee", email: "x" }, "name") // OK
getUserField({ id: 1, name: "Lee", email: "x" }, "age") // 에러
이렇게 해두면:
- 존재하지 않는 키(예: "age")를 쓰면 바로 컴파일 에러
- "User가 가진 키만 써라" 라는 조건을 타입으로 강제할 수 있다.
keyof = "이 타입이 가진 속성 이름들을 문자열 유니온으로 줘"
3. keyof typeof – 상수 객체의 key만 허용하기
실무에서 제일 자주 보는 패턴
상수 객체로 라우트, API 경로, 색상 토큰 등을 관리하고 있는데,
이 객체에 정의된 key만 쓸 수 있게 타입으로 막고 싶다.
3-1. 색상 토큰 예시
const COLORS = {
primary: "#3465ff",
danger: "#ff4d4f",
success: "#52c41a",
} as const
// COLORS가 가진 key 이름들만 허용하는 타입
type ColorName = keyof typeof COLORS
// "primary" | "danger" | "success"
function setThemeColor(name: ColorName) {
document.body.style.setProperty("--theme-color", COLORS[name])
}
setThemeColor("primary") // OK
setThemeColor("wrong") // 에러
여기서 일어나는 일은 딱 두 단계다.
typeof COLORS
→ COLORS라는 값의 타입을 가져온다.keyof typeof COLORS
→ 그 타입이 가진 key 이름만 유니온으로 뽑는다.
결과:"primary" | "danger" | "success"
이 패턴을 쓰면
- 문자열을 직접
"primary","danger"처럼 막 쓰지 않아도 되고 - COLORS 객체 기준으로만 유효한 값이 정해진다.
3-2. 라우트/메뉴 키에도 그대로 응용 가능
const ROUTES = {
home: "/",
settings: "/settings",
profile: "/profile",
} as const
// ROUTES의 key 이름만 허용
type RouteName = keyof typeof ROUTES
function navigate(name: RouteName) {
window.location.href = ROUTES[name]
}
navigate("home") // OK
navigate("dashboard") // 에러
이렇게 하면:
- 라우트 이름을 바꾸거나 추가했을 때
- 타입 에러로 잘못된 부분들을 먼저 발견할 수 있다.
keyof typeof obj = "이 객체에 실제로 존재하는 key만 쓸 수 있게 막자"
4. 언제 어떤 걸 떠올리면 되는지
4-1. typeof를 떠올릴 타이밍
- 이미 값(객체, 함수 등)이 있는데, 그 구조를 그대로 타입으로 쓰고 싶다.
- 타입 정의를 값과 따로 두 번 쓰고 싶지 않다.
const CONFIG = { ... } as const
type Config = typeof CONFIG
4-2. keyof를 떠올릴 타이밍
- "이 타입이 가진 키 이름들만 허용하고 싶다"는 요구가 있을 때.
- 특정 타입의 key만 인자로 받는 함수를 만들고 싶을 때.
type UserKey = keyof User
function getUserField(user: User, key: UserKey) { ... }
4-3. keyof typeof를 떠올릴 타이밍
- 상수 객체(ROUTES, COLORS, API_PATHS 등)를 이미 쓰고 있다.
- 이 객체에 정의된 key 이외의 문자열은 막고 싶다.
const API_PATHS = {
list: "/api/users",
detail: "/api/users/:id",
me: "/api/me",
} as const
type ApiPathName = keyof typeof API_PATHS
function fetchApi(name: ApiPathName) {
const url = API_PATHS[name]
// ...
}
5. 완전 핵심 요약
typeof
→ "이 값처럼 생긴 타입 하나 만들어 줘"keyof
→ "이 타입이 가진 속성 이름들만 문자열 유니온으로 줘"keyof typeof obj
→ "이 상수 객체에 실제로 있는 key만 쓸 수 있게 막자"
CONFIG, ROUTES, COLORS처럼 상수 객체 + 타입을 같이 다루는 연습을 하다 보면,
실무 코드에서 자연스럽게 typeof, keyof, keyof typeof를 떠올리게 된다
'FrontEnd > TypeScript' 카테고리의 다른 글
| TypeScript as const 이게 뭘까 (0) | 2025.12.18 |
|---|---|
| TypeScript 유틸리티 타입 Partial<T> – 부분만 채워도 되는 타입 만들기 (1) | 2025.12.14 |
| TypeScript 유틸리티 타입 Omit<T, K> – 필요 없는 필드만 쏙 빼고 쓰기 (0) | 2025.12.14 |
| TypeScript 유틸리티 타입 Pick<T, K> – 객체 타입에서 필요한 것만 뽑아 쓰기 (0) | 2025.12.13 |
| setTimeout() 반환값 정리 – 브라우저 vs Node에서 뭐가 다른지 (0) | 2024.11.24 |
