yamoo9 / likelion-FEQA

질문/답변 — 프론트엔드 스쿨, 멋사
29 stars 9 forks source link

[LAB-5] TypeScript 타입 에러 문제 #261

Closed seoohyeon closed 1 year ago

seoohyeon commented 1 year ago

질문 작성자

김서현

문제 상황

ReadMeeting.tsx파일에서 각각 28번째줄, 104번째줄에서 빨간줄이 뜹니다. 타입에러인듯한데,
여러 시도를 해보았으나 해답을 찾지못하였습니다.

const ShowCard = lazyMinLoadTime(() => import('./ShowCard'), 1000); <ShowCard cards={cards} />

프로젝트 저장소 URL

https://github.com/React-Project-lab5/React-Project-lab5
develop브랜치

src.zip

환경 정보

yamoo9 commented 1 year ago

당부의 말

@seoohyeon 님. 오류가 발생하면 오류 메시지를 알려주셔야 문제 원인 분석이 가능해요. 🥲

"의사 선생님. 아파요. 많이 아파요"라고 말하는 환자의 말처럼 "어디가? 어떻게? 언제부터?"라는 부분이 빠져있으면 의사 선생님은 환자에게 하나 하나 다시 물어봐야 해요. 😥

그러니까 질문을 작성할 때는 상황을 자세하게 알려줘야 빠른 진단이 가능해요. 🥹

"의사 선생님. 어제 저녁 먹고 밤부터 배가 살살 아프더니, 밤새 못잤어요. 지금도 배가 아파요. 이 부분이에요. 여기.. 위쪽이요."

문제 분석

문제를 진단해보니 컴포넌트 반환 타입(return type)이 lazyMinLoadTime 함수의 타입과 호환되지 않는다는 오류 메시지입니다.

Types of property 'default' are incompatible. Type '({ cards }: Props) => Element[]' is not assignable to type 'ComponentType'. Type '({ cards }: Props) => Element[]' is not assignable to type 'FunctionComponent'. Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, keyts(2322) lazyMinLoadTime.tsx(4, 12): The expected type comes from the return type of this signature.


TypeScript에 의해 표시된 오류 과정을 찬찬히 살펴봅시다.

lazyMinLoadTime 함수의 동적 호출(dynamic import) 반환 타입은 Promise<{ default: T }> 입니다.

반면 ShowCard 컴포넌트 반환 타입은 Element[]입니다. 문제 원인을 확인했네요!

문제 해결

문제 해결 방법은 컴포넌트 반환 타입을 Element[]가 아니라, JSX.Element로 내보내도록 설정하면 됩니다.

아래 이미지를 보면 TypeScript가 아무런 경고를 하지 않아 오류를 찾기 어려웠을 겁니다.

그런데 컴포넌트 반환 타입(return type)을 JSX.Element로 설정 했었다면 손쉽게 오류를 확인할 수 있었을 거에요. 즉, 컴포넌트를 정의할 때 반환 타입을 생략해서 문제가 무엇인 지 확인하기 어려웠던 것이지요.

반환 타입 오류는 React.Fragment를 사용해 Element[]를 감싸 반환하면 JSX.Element가 되므로 해결됩니다. 😊

아래처럼 ShowCard 컴포넌트 코드를 수정합니다.

export default function ShowCard({ cards }: Props): JSX.Element {
  // ...
  return (
    <>
      {cards.map((value, index: number) => (
        <div key={index} className={classes.showUsers}>
          <span>{value.title.join(' ')}</span>
          <span>{value.address}</span>
          <span>{value.detail}</span>
          <span>{value.cardData.slice(0, 15)}</span>
          <span className={classes.lastSpan}> {value.cardData.slice(16)}</span>
        </div>
      ))}
    </>
  );
}

반환 타입에 맞춰 코드를 수정하면 TypeScript는 더 이상 오류를 표시하지 않습니다. 😃

seoohyeon commented 1 year ago

@yamoo9 죄송합니다 ㅠ 어제 컴퓨터가 작동이 제대로 안되서 캡처도구가 말을 듣지 않아... 부득이하게 글로써 설명하려 했던점 양해부탁드립니다...ㅠㅠㅠ(지금 컴퓨터가 엄청 느리고 상태가 안좋은 상태입니다..ㅠㅠ 진짜 죄송합니다)

yamoo9 commented 1 year ago

@yamoo9 죄송합니다 ㅠ 어제 컴퓨터가 작동이 제대로 안되서 캡처도구가 말을 듣지 않아... 부득이하게 글로써 설명하려 했던점 양해부탁드립니다...ㅠㅠㅠ(지금 컴퓨터가 엄청 느리고 상태가 안좋은 상태입니다..ㅠㅠ 진짜 죄송합니다)

아... 컴퓨터가 그런 상황 이었군요 ㅠㅡㅠ 아무쪼록 프로젝트 마무리 한 후 클린 포멧 하여 쾌적한 환경 만들어 보세요 @seoohyeon 님 ^^