-
An index signature parameter type cannot be a literal type or a generic typeStudying/JavaScript 2023. 8. 20. 21:48
문제 발생
PortfolioItem.tsx 컴포넌트에서 사용할 디자인을 별도로 관리하던 중 발생한 문제입니다.
PortfolioItem은 포트폴리오 섹션(App, Web, Illustration...)에 따라 크기 비율이 다릅니다. 따라서 디자인 토큰처럼 별도 관리하려고 했습니다.
무슨 포트폴리오인지 구분하기 위해 props를 받게 되고, 그 props를 더 정확히 할 Section 타입을 정의했습니다.type Section = 'Android/iOS' | 'Web' | 'Illustration' | 'Graphics' | 'Video';
그리고 스타일 객체를 위한 타입을 정의했습니다.
// src/types/style.ts import { Section } from "./portfolio" export type PortfolioItemSize = { [key: Section]: { // 에러 발생 aspectRatio: string } }
그리고 다음과 같은 에러가 발생했습니다.
An index signature parameter type cannot be a literal type or a generic type
원인
key 타입은 string, number, symbol 혹은 리터럴 타입일 수 없다고 합니다.
해결 방법
해결 방법은 여러 가지가 있었습니다.
1. mapped type 사용하기
// enum일 경우 enum EmailStatus { Read = 'READ', Unread = 'UNREAD', Draft = 'DRAFT', } // union일 경우 type EmailStatuses = 'Read' | 'Unread' | 'Draft'; // 👇️ 아래와 같이 사용(인터페이스 x) type Status = { [key in EmailStatus]: string; };
인덱스 시그니처에 in 키워드를 사용하는 방법입니다.
단, 만약 mapped type을 인터페이스에서 타입 별칭 대신 사용한다면 에러가 발생한다고 합니다.
interface Status { // ⛔️ Error [key in EmailStatus]: string; };
mapped type은 enum과 union 프로퍼티에 한하여 사용하기로 합시다.
2. Record utility type 사용하기
Record 유틸리티 타입은 키, 값의 type을 기반으로 구성됩니다.
// emum 사용할 경우 enum EmailStatus { Read = 'READ', Unread = 'UNREAD', Draft = 'DRAFT', } type Status = Record<EmailStatus, string> // union 사용할 경우 type EmailStatuses = 'Read' | 'Unread' | 'Draft'; // Record utility type type StatusFromUnion = Record<EmailStatuses, string>
결과는 mapped type을 사용했을 때와 동일합니다.
참고 사이트
'Studying > JavaScript' 카테고리의 다른 글