Error: Type 'K' cannot be used to index type 'SelectedEventInfo'

Jongco·2023년 6월 28일
1

Intro

프로젝트 도중 제네릭 관련해서 문제가 발생했다. 분명히 내 상식 안에서는 이 코드가 작동해야 하는데 작동하지 않았고, 이를 통해 제네릭에 대해서 공부하는 계기가 되었다.

문제점

바로 아래에 있는 코드에서 문제가 발생했다.

const initialSelectData: SelectedEventInfo = {
  eventId: 0,
  memo: '',
  date: dayjs().format('YYYY.MM.DD'),
  situation: '미납',
  nickname: '',
  amount: 0,
  ground: '지각',
};

const func = <T extends SelectedEventInfo, K extends keyof T>(...arg: K[]) => {
  const newObj: Partial<Record<K, T[K]>> = {};

  arg.forEach((key) => {
    if (key in initialSelectData) {
      //Error: Type 'K' cannot be used to index type 'SelectedEventInfo'
      newObj[key] = initialSelectData[key]; 
    }
  });

  return newObj;
};

K는 SelectedEventInfo의 인덱스 타입이 될 수 없다는 에러가 빵빵 터지고 있다. 😢
T는 SelectedEventInfo를 확장한 타입이고,
K는 T의 키값이니까 당연히 initialSelectData의 K인덱스는 존재해야 마땅하다고 생각했다.

해결 방법

위에는 내가 놓친 부분이 있었다. 바로 T는 SelectedEventInfo를 확장한 부분이라는 것이다.
확장을 했다는 것은 SelectedEventInfo 이 외에도 다른 값이 추가적으로 들어올 수 있다는 의미이다.

만약에 확장된 T에 🍎: 3 이란 값이 추가적으로 들어왔다고 생각해보자.
그렇게 되면 확장될 수 있는 T의 key값인 K에도 🍎 값이 들어있어야 하는 게 당연하고,
당연하게도 SelectedEventInfo[🍎]는 존재하지 않는 값이기에 에러가 발생하는 것이었다.

SelectedEventInfo가 여러번 반복되어 보기 싫어서 단순히 제네릭을 사용하려고 했을 뿐인데,
지금까지 얼마나 생각없이 제네릭을 사용하는지 알 수 있었던 날이었다..
정확하게 사용하려면 아래와 같이 사용하면 될 거 같다.

const func = <K extends keyof SelectedEventInfo>(...arg: K[]) => {
  const newObj: Partial<SelectedEventInfo> = {};

  arg.forEach((key) => {
    if (key in initialSelectData) {
      newObj[key] = initialSelectData[key];
    }
  });

  return newObj;
};

0개의 댓글