자바스크립트 개발자라면 typeof 연산자에 익숙할 겁니다. 값의 타입을 문자열로 알려주는 편리한 도구죠. 하지만 타입스크립트의 typeof는 단순한 연산자를 넘어, 타입 시스템의 강력한 도구로 활용됩니다.
1. 자바스크립트의 typeof (런타임)
자바스크립트에서 typeof는 코드가 실행되는 런타임에 동작합니다. 주어진 값의 타입을 문자열로 반환하는 역할을 해요.
typeof 123; // "number"
typeof "hello"; // "string"
typeof { a: 1 }; // "object"
이때, typeof가 반환하는 결과는 'number', 'string', 'object' 같은 문자열 값입니다.
2. 타입스크립트의 typeof (타입 쿼리 연산자)
타입스크립트의 typeof는 컴파일 타임에 동작하며, 특정 값으로부터 타입을 추출하는 역할을 합니다. 즉, 런타임에 존재하는 값의 구조를 바탕으로 타입스크립트 타입 시스템에서 사용할 수 있는 타입을 만들어내는 것이죠.
const msg = "hello";
type MyType = typeof msg;
// MyType은 "hello"라는 리터럴 타입이 됩니다.
// (일반 string이 아니라, 정확히 "hello"라는 값만 허용)
let x: MyType = "hello"; // ✅
x = "hi"; // ❌
요약하자면:
- JS 런타임: typeof msg는 'string'이라는 문자열을 반환합니다.
- TS 컴파일 타임: typeof msg는 'hello'라는 리터럴 타입을 추출합니다.
3. typeof를 활용한 타입 추출 패턴
typeof는 주로 이미 존재하는 변수나 객체의 타입을 안전하게 재사용할 때 빛을 발합니다. 몇 가지 유용한 패턴을 살펴볼게요.
(1) 변수/객체 타입 참조
복잡한 객체 타입을 일일이 다시 작성할 필요 없이 typeof로 쉽게 가져올 수 있습니다.
const user = {
id: 1,
name: "Alice",
active: true,
};
// user 변수의 구조를 그대로 가져와서 타입 정의
type User = typeof user;
/*
type User = {
id: number;
name: string;
active: boolean;
}
*/
(2) 배열 요소 타입 추출
배열 타입에서 특정 요소의 타입을 뽑아낼 때 유용합니다. [number]를 사용해 인덱스 시그니처를 참조하는 방식입니다.
const arr = [10, 20, 30];
type ArrType = typeof arr; // number[]
type ElemType = typeof arr[number]; // number
const 어서션을 사용하면 더 정교한 타입 추출이 가능합니다.
const arrConst = ['a', 'b', 'c'] as const;
type ArrConstType = typeof arrConst; // readonly ["a", "b", "c"]
type ElemConstType = typeof arrConst[number]; // "a" | "b" | "c"
(3) keyof와 함께 활용
keyof 연산자와 결합하면 객체의 키(key) 또는 값(value) 타입을 유니언 타입으로 추출할 수 있습니다.
const colors = {
red: "#ff0000",
blue: "#0000ff",
};
// 키 타입을 가져와서 "red" | "blue" 생성
type ColorKey = keyof typeof colors;
// 값 타입을 가져와서 string 생성
type ColorValue = (typeof colors)[keyof typeof colors];
(4) 유틸리티 타입과 결합
ReturnType이나 Parameters와 같은 내장 유틸리티 타입과 함께 사용하면 함수 시그니처에서 반환 값이나 매개변수 타입을 쉽게 추출할 수 있습니다.
function getUser(id: number) {
return { id, name: "Alice" };
}
type R = ReturnType<typeof getUser>; // { id: number; name: string }
type P = Parameters<typeof getUser>; // [id: number]
이 패턴은 특히 복잡한 함수 타입을 재사용해야 할 때 매우 효과적입니다. 예를 들어, Redux 상태 관리에서 초기 상태(initialState)의 타입을 typeof로 추출해 리듀서 상태 타입으로 재활용하는 방식이 대표적입니다.
4. 핵심 정리
| 구분 | JS 런타임 typeof | TS 타입 시스템 typeof |
| 결과 | 'string', 'object' 등 문자열 | string, { id: number } 등 타입 |
| 시점 | 코드가 실행되는 런타임 | 코드를 분석하는 컴파일 타임 |
| 목적 | 값의 실제 타입을 확인 | 값의 타입을 가져와서 타입 시스템에 활용 |
타입스크립트의 typeof는 단순히 타입을 확인하는 것을 넘어, **"컴파일러에게 저 값의 타입을 가져와서 타입으로 사용해줘"**라고 명령하는 도구입니다. 이를 통해 코드 중복을 줄이고, 타입 안전성을 높여 유지보수하기 쉬운 코드를 작성할 수 있습니다.