Next.js Image 컴포넌트의 width, height 속성 옵셔널 타입에 따른 런타임 에러 컴파일 에러로 개선하기

제이슨·2024년 5월 23일
1

문제 상황

Next.js에서 제공하는 Image 컴포넌트를 사용하여 이미지를 표시하는 ContentsImageWrapper 컴포넌트를 만들었다.

컴파일 타임에 타입 에러가 잡히지 않았기 때문에 제대로 동작할 거라고 생각했지만,
타입 에러 발생 스크린샷

런타임 환경에서 에러를 밷었다.

뭐가 문제였을까...?

원인 분석

컴파일 타임에 오류가 잡히지 않았던 이유는 ImageProps 타입 내부에서 widthheight 속성이 옵셔널로 선언되어 있었기 때문이다.

ImageProps 타입 정의 스크린샷

그럼 런타임에 오류가 터졌던 이유는 뭘까? 🤔

NEXT.JS 공식 문서에서 width, height 값은

  • fill 속성을 가진 경우
    * true일 경우, 이미지의 크기가 컨테이너(부모 엘리먼트)의 크기에 맞게 조정되며, 가로세로비를 유지한다.
  • 정적으로 임포트된 이미지인 경우
    정적 이미지란 외부 URL이 아닌 프로젝트 내부에 있는 이미지 파일을 의미한다.
    Next.js는 정적 이미지를 자동으로 최적화해준다. 정적 이미지는 빌드 타임에 이미지의 정보(너비와 높이 등)를 알 수 있기 때문에 width와 height 값을 기입할 필요가 없다.
    가 아니면 필수값이라고 소개되어있다.

해결 방법

next/imageImageProps를 상속받은 뒤, widthheight를 필수 속성으로 재정의한 ContentsImageWrapperProps 인터페이스를 만든다.

// ...

interface ContentsImageWrapperProps extends ImageProps {
  width: number;
  height: number;
}

function ContentsImageWrapper({
  src,
  alt,
  width,
  height,
  className,
}: ContentsImageWrapperProps): JSX.Element {
  return (
    <div className={mergeClassNames('w-[100%] h-[auto] flex justify-center')}>
      <Image
        src={src}
        alt={alt}
        width={width}
        height={height}
        className={className}
        layout='responsive'
        objectFit='contain'
      />
    </div>
  );
}

export default ContentsImageWrapper;

이제 width와 height 값을 입력할 경우, 컴파일 에러가 잘 나오는 것을 확인할 수 있다.
해결 후 스크린샷

문제 해결에 집중한 글이기 때문에, 코드 퀄리티를 개선하는 과정은 담지 않았지만... 기회가 된다면 리팩토링하는 과정을 담은 글을 써보고 싶다 😢

profile
계속 읽고 싶은 글을 쓰고 싶어요 ☺

0개의 댓글