[Typescript] keyof 타입 연산자

Bam·2023년 9월 6일
0

Typescript

목록 보기
30/32
post-thumbnail

keyof

keyof 타입 연산자(이하 keyof 또는 keyof 연산자)는 객체 타입에서 객체의 키(프로퍼티)를 string 또는 number 리터럴 유니온 타입으로 생성하는 연산자입니다.

말로하면 잘 안와닿을 수 있기에 실제 코드를 하나 보면서 keyof를 이해해봅시다.

type Member = {
  id: number;
  name: string;
};
type M = typeof Member; // type M = 'id' | 'name';

위 코드에서 typeof 연산자Member 타입의 키인 'id', 'name'을 추출하게 됩니다. 따라서 M 타입에는 'id' | 'name'string 리터럴 유니온 타입이 정의되게 됩니다.

인덱스 시그니쳐와 keyof

만약 타입에 인덱스 시그니쳐를 사용하고 있다면 keyof는 키가 아닌 키의 타입을 따라가게 됩니다.

이때 인덱스 시그니쳐가 string또는 number 타입일 때만 사용가능합니다.

type Languages = {
  [lan: string]: string;
};
type L = keyof Languages; // type L = string | number;

type Numbers = {
  [num: number]: number;
};
type N = keyof Numbers; // type N = number;

첫 번째 예시에서 L의 타입이 string이 아니라 number인데요. 이런 일이 발생하는 원인은 TS 2.9 버전의 노트에 적혀있습니다.

Given an object type X, keyof X is resolved as follows:

  • If X contains a string index signature, keyof X is a union of string, number, and the literal types representing symbol-like properties, otherwise
  • If X contains a numeric index signature, keyof X is a union of number and the literal types representing string-like and symbol-like properties, otherwise
  • keyof X is a union of the literal types representing string-like, number-like, and symbol-like properties.

간단히 요약하자면 객체 X를 주었을 때 문자열 인덱스 시그니쳐는 문자열/숫자/리터럴/심볼과 같은 프로퍼티 포함하는 합집합 타입이 되고, 숫자 인덱스 시그니쳐는 숫자/리터럴/ 문자열, 심볼과 같은 프로퍼티를 나타내는 합집합 타입 이라는 것 입니다.

그리고 이 원인은 자바스크립트의 동작과 관련이 있는데, 자바스크립트는 객체를 해석할 때 숫자를 문자열로 변환하기 때문이라고 합니다. (즉, "0"와 0는 같다고 봄)

만약 이런 일을 방지하고 싶다면 컴파일러 설정(tsconfig)를 설정하는 방법이 있습니다.

{
  "compilerOptions": {
    (...)
    "keyofStringsOnly": true,
  },
}

설정 전

설정 후

0개의 댓글