TypeScript에는 객체 기반 타입을 더욱 강력하게 다뤄 주는 두 가지 중요한 키워드가 있습니다. 바로 keyof와 typeof입니다. 둘을 함께 활용하면 “실제 객체의 구조”로부터 타입을 자동 생성할 수 있으며, 유지보수성과 타입 안정성을 높일 수 있습니다.
특히 API 응답 모델링, 폼 검증, Config 객체 타입 자동 생성 등 실무에서 매우 자주 사용되는 문법입니다.
typeof — 값으로부터 타입 가져오기
typeof는 JavaScript의 typeof와 완전히 다른 목적을 가집니다. TypeScript에서는 “값의 타입을 타입으로 가져오는” 용도로 쓰입니다.
const user = {
id: 1,
name: "Alice",
};
type User = typeof user;
// User = { id: number; name: string }
즉, 실제 객체의 구조를 그대로 타입에 반영할 수 있습니다. 별도의 타입을 중복 선언할 필요가 없어 유지보수성이 좋아집니다.
keyof — 객체의 키(key)로 구성된 타입 생성
keyof는 “타입의 모든 프로퍼티 이름을 Union 타입으로 반환”합니다.
type User = {
id: number;
name: string;
age: number;
};
type UserKeys = keyof User;
// "id" | "name" | "age"
이 키 값은 문자열 리터럴 유니온으로 변환되기 때문에, 속성명을 제한하고 싶은 경우 매우 유용합니다.
keyof + typeof 조합
실무에서는 typeof로 객체 타입을 가져온 뒤 keyof로 key들을 추출하는 패턴이 가장 많이 사용됩니다.
const config = {
host: "localhost",
port: 3306,
user: "root",
};
type ConfigKey = keyof typeof config;
// "host" | "port" | "user"
이 패턴은 상수 객체에서 자동으로 타입을 만드는 데 최적화되어 있습니다.
실제 활용 예제
1. 안전한 객체 접근 함수 만들기
function getValue<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const person = { name: "Alice", age: 20 };
getValue(person, "name"); // OK
getValue(person, "address"); // 오류
keyof 덕분에 객체에서 존재하는 key만 인자로 전달할 수 있습니다. 폼 검증, API 응답 파싱 등에 유용합니다.
Record와 함께 사용하는 패턴
keyof로 key들을 추출하면 Record와 조합해 타입 안정성을 극대화할 수 있습니다.
const roles = {
admin: "관리자",
user: "일반 사용자",
guest: "게스트",
} as const;
type RoleKey = keyof typeof roles;
// "admin" | "user" | "guest"
const roleMap: Record<RoleKey, number> = {
admin: 1,
user: 2,
guest: 3,
};
객체 키의 변경이 있으면 타입이 자동으로 업데이트되어 유지보수성이 탁월합니다.
keyof의 타입 제한 기능
✔ 객체의 특정 키만 허용
type User = { id: number; name: string; age: number };
function update(user: User, key: keyof User, value: any) {
user[key] = value;
}
update({ id: 1, name: "Bob", age: 22 }, "name", "Alice"); // OK
update({ id: 1, name: "Bob", age: 22 }, "unknown", "Alice"); // ❌
keyof는 타입 기반의 안전한 동적 프로퍼티 접근을 가능하게 합니다.
typeof와 유니온 타입 자동 생성
객체가 가진 값으로부터 유니온 타입을 자동으로 생성할 수도 있습니다.
const Status = {
OK: 200,
NOT_FOUND: 404,
ERROR: 500,
} as const;
type StatusCode = (typeof Status)[keyof typeof Status];
// 200 | 404 | 500
enum을 대체하는 패턴으로 프론트엔드에서 자주 사용됩니다. 런타임 코드 생성이 없기 때문에 성능과 안정성 모두 뛰어납니다.
keyof / typeof를 이해하면 가능한 실무 활용들
- Config 객체 기반 자동 타입 생성
- API 응답 모델링 자동화
- 폼 입력 필드의 key 안전성 보장
- DB 컬럼명 안전하게 사용
- enum 대체 패턴
- Record와 결합해 key/value mapping 구현
특히 typeof + keyof 조합은 레거시 JS 프로젝트를 TS로 전환할 때 매우 강력한 도구입니다.
keyof와 typeof는 TypeScript의 객체 타입 설계를 정교하게 만드는 키워드입니다. 값 기반으로 타입을 자동 생성하고, key를 안전하게 제한하고, 복잡한 구조를 유지보수성 높게 관리할 수 있도록 합니다.
- typeof = 값의 타입을 가져오는 도구
- keyof = 객체 타입의 key를 유니온으로 생성
- typeof + keyof 조합 = 실무에서 가장 많이 쓰는 패턴
