TypeScript 개념 정리 - keyof 타입 연산자

dobby·2025년 6월 27일
0

타입스크립트

목록 보기
9/11
post-thumbnail

keyof 타입 연산자

keyof 연산자는 객체 타입에서 객체의 키 값들을 숫자나 문자열 리터럴 유니언으로 생성한다.

아래의 타입 P는 'x' | 'y'와 동일한 타입이다.

type Point = { x: number; y: numer;};
type P = keyof Point;

요약하자면, 자바스크립트에서의 typeof 는 변수의 타입을 반환하고, keyof 는 객체 또는 인터페이스의 키 값을 타입으로 반환하는 것이다.

만약 타입이 string이나 number 인덱스 시그니처를 가지고 있다면, keyof 는 해당 타입을 리턴한다.

type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish; // number;

type Mapish = { [k: string]: boolean };
type M = keyof Mapish; // string | number

여기서 주목할 점은 M의 타입이 string | number 라는 점이다.
Javascript 객체 키는 항상 문자열을 강제하기 때문에 obj[0]obj['0']과 동일하다
typescript에서는 number 키도 자동으로 string으로 변환되기 때문에 안전하게 number | string 으로 확장해서 보는 것이다.

그래서 type Arrayish = { [n: number]: unknown }; 이긴 하지만 n에 '1'과 같은 문자열 숫자 키도 허용된다.


keyof 타입은 매핑된 타입과 함께 사용할 때 특히 유용하다.
인터페이스를 정의하고 keyof 를 사용하여 해당 인터페이스의 모든 속성 이름을 가져올 수 있다.

interface Person {
 name: string;
 age: number;
 address: string;
}

type PersonKeys = keyof Person;

PersonKeys는 "name" | "age" | "address" 라는 문자열 리터럴 유니온 타입이 된다.

이렇게 생성된 문자열 유니온 타입을 사용하여 객체의 속성 이름을 동적으로 참조하거나 검사할 수 있다.


사용 예시

type Filter = {
  size: string[];
  breed: string[];
}
const [selectedFilter, setSelectedFilter] = useState<Filter>({
  size: [],
  breed: [],
});

const handleFilterSelect = (filterKey: keyof Filter, filterName: string) => {
  const updatedFilter = { ...selectedFilter };
  
  // 이미 배열에 저장되어 있는 filter 값인 경우 배열에서 제거
  if(selectedFilter[filterKey].includes(filterName)) {
   updatedFilter[filterKey] = updatedFilter[filterKey].filter((name) => name !== filterName));
    
    selectedFilter(updatedFilter);
    return;
  }
  // 배열에 저장되어 있지 않은 filter 값인 경우 배열에 추가
  updatedFilter[filterKey].push(filterName);
  setSelectedFilter(updatedfilter);
}

keyof typeof

const handlePrintOptionButtonClick = (groupIndex: number, buttonIndex: number) => {
 ...
 const selectedKey = ButtonTitleKey[printMod as keyof typeof ButtonTitleKey][groupIndex];
}

keyof typeof 를 사용해 객체의 키 값을 타입으로 가져왔다.
-> typeof ButtonTitleKeyButtonTitleKey 객체의 타입을 가져오고, keyof 를 사용해 해당 객체의 모든 키 값을 가져온다.

그렇다면 아래와 같은 상황에서는 어떻게 사용해야 할까?

const person = {
 name: 'jiwoo',
 age: 10,
}

console.log(typeof person); // 'object'

typeof 만 사용했을 경우, 이런식으로 'object'라는 타입을 반환하게 되고, keyof 를 사용하면 해당 객체의 키 값을 유니온 타입으로 반환한다고 했는데 어쩔 때 같이 사용해야 할까?


keyof typeof를 같이 사용하는 경우

const bmw = { name: 'BMW', power: '1000hp' };

type CarLiteraltype = keyof typeof bmw;

let carPropertyLiteral: CarLiteraltype;
carPropertyLiteral = 'name' // OK
carPropertyLiteral = 'power' // OK
carPropertyLiteral = 'anyOther' // Error...

위 예시처럼, 미리 interface 등으로 타입 지정이 되어 있지 않고 값만 할당되어 있는 경우 object에서 바로 사용하고 싶은 경우에 typeof와 keyof를 같이 사용하여 해당 객체의 키 값으로 이루어진 유니온 타입을 얻을 수 있다.

profile
성장통을 겪고 있습니다.

0개의 댓글