우아한 타입스크립트 with 리액트를 읽다가 keyof, typeof를 제대로 알고 써야겠다는 생각이 들었다. 이전까지 keyof typeof는 그냥 동작하니까 써온 것인데 keyof와 typeof가 정확히 어떤 역할을 하고 keyof typeof object가 어떻게 동작하는지 알아보았다.

keyof

keyof 연산자는 객체 타입에서 객체의 키 값들을 숫자나 문자열 리터럴 유니언을 생성합니다.
keyof 예제
출처 : Keyof Type Operator

keyof는 type이나 interface에서 객체 키 값을 가져오는 연산자로 생각할 수 있다.

typeof

TypeScript는 타입컨텍스트에서 변수나 프로퍼티의 타입을 추론할 수 있는 typeof 연산자를 추가합니다.
typeof 예제
출처 : Typeof Type Operator

간략하게 말하면 typeof는 값을 type으로 추론하는 것을 도와준다.

keyof typeof 가 의미하는 것

1const people = {
2 korean: "Korean",
3 chines: "Chines",
4 japanese: "Japanese"
5};
6
7type PeopleType = typeof people;

PeopleType은 아래와 같다.

1// type PeopleType = {
2// korean:string;
3// chines:string;
4// japanese:string;
5// }

keyof는 객체 타입에서 객체 키 값의 유니온을 생성한다고 했다. 그래서 PeopleType에 keyof를 사용하면 아래와 같다.

1type P = keyof PeopleType;
2
3// type P = "korean" | "chines" | "japanese"

value를 constants 값으로 활용하기

value를 union type으로 활용하고 싶다면

1const people = {
2 korean: "Korean",
3 chines: "Chines",
4 japanese: "Japanese"
5} as const;
6
7type PeopleType = typeof people;
8type PeopleKey = keyof PeopleType;
9type PeopleValue = PeopleType[PeopleKey];

필요할 때 마다 생성하면 된다. 하지만 불편하다.

유틸 타입으로 만들어서 활용하기

key, value를 union타입으로 만들때 '유틸 타입으로 만들어서 활용하면 괜찮지 않을까' 하는 생각이 들어서 만들어보았다.

1type RecordKey<T> = keyof T;
2type RecordValue<T, K extends keyof T> = T[K];
3
4type PeopleType = typeof people;
5type PeopleKey = RecordKey<PeopleType>;
6type PeopleValue = RecordValue<PeopleType, PeopleKey>;