keyof
, typeof
, in
연산자 실전 사용법TypeScript는 정적 타입 시스템을 통해 코드 안정성을 크게 향상시켜줍니다.
그중에서도 keyof
, typeof
, in
은 자주 사용되면서도 초보자에게 혼란을 줄 수 있는 연산자입니다.
이번 글에서는 이 세 가지 연산자의 개념부터 실전 활용 예시에 대해 정리해보겠습니다.
keyof
는 객체 타입의 키 값들만 union 타입으로 반환합니다.
type User = {
id: number;
name: string;
isActive: boolean;
};
type UserKeys = keyof User; // "id" | "name" | "isActive"
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { id: 1, name: "ohhaio" };
const name = getValue(user, "name"); // "ohhaio"
typeof
는 변수나 값의 타입을 추론할 때 사용됩니다.
JavaScript
의 typeof
는 런타임에서 작동하지만, TypeScript
의 typeof
는 타입 레벨에서 작동합니다.
const config = {
apiUrl: "https://example.com",
timeout: 3000,
};
type Config = typeof config;
// {
// apiUrl: string;
// timeout: number;
// }
const colors = {
primary: "#4b79cf",
secondary: "#f5f5f5",
} as const;
type ColorKey = keyof typeof colors; // "primary" | "secondary"
type ColorValue = (typeof colors)[ColorKey]; // "#4b79cf" | "#f5f5f5"
as const
와 함께 사용하면 literal type
으로 고정되어 안전성이 높아집니다.in
은 타입 수준에서 사용될 경우 Mapped Type
생성에 쓰입니다.
type Keys = "a" | "b" | "c";
type Flags = {
[K in Keys]: boolean;
};
// {
// a: boolean;
// b: boolean;
// c: boolean;
// }
type ApiResponse<T> = {
[K in keyof T]: {
data: T[K];
loading: boolean;
error: string | null;
};
};
type User = {
name: string;
age: number;
};
type UserApiState = ApiResponse<User>;
/*
{
name: { data: string; loading: boolean; error: string | null; };
age: { data: number; loading: boolean; error: string | null; };
}
*/
keyof
는 객체 키를 타입으로 추출할 수 있어, 타입 안전한 접근 함수에 적합합니다.typeof
는 런타임 객체의 타입을 타입 시스템에 반영할 수 있어, 상수 기반 코드에 강력합니다.in
은 동적인 타입 생성 및 반복적인 타입 선언을 자동화할 때 매우 유용합니다.