TypeScript에서 No index signature 오류 해결

Table of Contents

오류가 발생하는 원인

아래 코드에서는 MIME_TYPE_MAP 부분에서 오류가 발생함, 왜냐하면 MIME_TYPE_MAP[file.mimetype]로 접근할 때, file.mimetype은 일반적으로 string 타입으로 추론

import multer from "multer";

const MIME_TYPE_MAP = {
  "image/png": "png",
  "image/jpg": "jpg",
  "image/jpeg": "jpeg",
};

const ext = MIME_TYPE_MAP[file.mimetype];


MIME_TYPE_MAP의 키 타입
TypeScript는 이 객체 MIME_TYPE_MAP의 키를 "image/png" | "image/jpg" | "image/jpeg"로 제한, TypeScript는 MIME_TYPE_MAP이 리터럴 유니온 타입 키를 가진 객체라고 이해


file.mimetype의 타입
file.mimetype의 타입은 보통 string으로 추론


TypeScript는 컴파일 타임에 file.mimetype이 항상 MIME_TYPE_MAP의 키에 포함된다고 보장할 수 없음

const file = { mimetype: "application/json" }; // MIME_TYPE_MAP에 없는 값
const ext = MIME_TYPE_MAP[file.mimetype]; // 이 접근은 undefined!


file.mimetype가 MIME_TYPE_MAP의 키가 아니면, 런타임에서 undefined를 반환, 이는 TypeScript가 방지하려는 안전성 문제


1. 타입 단언

const ext = MIME_TYPE_MAP[file.mimetype as keyof typeof MIME_TYPE_MAP];


2. 타입 가드 사용

if (file.mimetype in MIME_TYPE_MAP) {
  // const ext = MIME_TYPE_MAP[file.mimetype]; // 오류 발생
  const ext = MIME_TYPE_MAP[file.mimetype as keyof typeof MIME_TYPE_MAP];
}


타입 내로잉(Narrowing)

function isValidMimeType(mimetype: string): mimetype is keyof typeof MIME_TYPE_MAP {
  return mimetype in MIME_TYPE_MAP;
}

// mimetype is keyof typeof MIME_TYPE_MAP은 file.mimetype이 MIME_TYPE_MAP의 키임을 TypeScript에 명시적으로 알림

if (isValidMimeType(file.mimetype)) {
    const ext = MIME_TYPE_MAP[file.mimetype];
} else {
    throw new Error("Unsupported MIME type");
}


3. Record 타입 사용

Record를 사용해서 MIME_TYPE_MAP의 키를 더 넓은 범위로 정의 예를 들어 Record<string, string> 타입으로 선언하면, string 키에 대해 동적 접근이 허용함

const MIME_TYPE_MAP: Record<string, string> = {
  "image/png": "png",
  "image/jpg": "jpg",
  "image/jpeg": "jpeg",
};

const ext = MIME_TYPE_MAP[file.mimetype];


type test= {
  [key: string]: string
}

const MIME_TYPE_MAP: test = {
  "image/png": "png",
  "image/jpg": "jpg",
  "image/jpeg": "jpeg",
};

const ext = MIME_TYPE_MAP[file.mimetype];


4. 유니온 타입 사용

type MIME_TYPE = "image/png" | "image/jpg" | "image/jpeg";
const ext = MIME_TYPE_MAP[file.mimetype as MIME_TYPE];


type FileWithMimeType = {
  mimetype: keyof typeof MIME_TYPE_MAP;
};

const file: FileWithMimeType = {
  mimetype: "image/png", // 유효한 값만 가능
};

const ext = MIME_TYPE_MAP[file.mimetype]; // 안전


5. 직접 지정

const file: { mimetype: "image/png" | "image/jpg" | "image/jpeg" } = { mimetype: "image/png" };
const ext = MIME_TYPE_MAP[file.mimetype];



Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x