Typescript Record Utiliy

6116 단어 typescripttypescript

진행중인 토이프로젝트 작업 중에, ContextAPI 의 초기 상태를 정의해야 하는 일이 있었다.

type Day = "월" | "화" | "수" | "목" | "금" | "토" | "일";

type Alarm = {
    day: Day;
    time: string;
    title: string;
    content: string;
}

const days: Day[] = ["월", "화", "수", "목", "금", "토", "일"];

위 코드에 정의된 것 중, Day를 Object의 각 key로, Alarm List를 value로 가지게 하는 작업이 있었다.
자바스크립트라면

const initialState = days.reduce((acc, cur) => {
  acc[cur] = [];
  return acc;
}, {});

위와 같이 단순하게 작업 할 수 있지만 Typescript의 경우에는 단순하지 않다.

우선 acc[cur] 이부분부터 에러를 뱉는다.
이유는 cur이 명시적으로 any로 타입스크립트 상에서 추론되기 때문이다.
any를 사용하지 않으려, tsconfig.json에서 noImplicitAny 옵션을 설정했다.

해결방법을 찾아보던 중, TypeScript의 Utiliy에 있는 Record를 사용하기로 했다.

Record는 객체를 생성 할 때, Key와 Value를 Type, Interface를 사용하게 해준다.

사실, 하드코딩으로 월요일부터 금요일까지 작성하게 되면 간단하긴 하지만 타입스크립트에 대해서 알아가는 중이기 때문에 하드코딩은 지양했다.

type AlarmListObj = {
    [key in Day]: Alarm[];
};

const initialState: AlarmListObj = days.reduce<Record<Day, Alarm[]>>((acc, cur) => {
    acc[cur] = [];

    return acc;
}, {} as AlarmListObj); 

최종적으로, 위와 같이 코드를 작성하여 초기값을 구성하였다.
reduce에 쓰이는 초기값 '{}' 에서도 에러가 발생하였는데, 빈 객체는 Record<Day, Alarm[]>에 부합하지 않기 때문에 에러를 발생시킨다.
이는, 빈 객체라도 타입스크립트보다 결국 결과값을 개발자가 더 많이 알고 있는 상태기 때문에 as assertion을 사용해도 무방하다고 생각하고 해결하였다.

타입스크립트는 알면 알수록 까다롭지만, 후에 모두 작성하고 나면 디버깅이나 코드를 한눈에 보기가 자바스크립트보다 좋을 것 같다.

좋은 웹페이지 즐겨찾기