💥 문제 상황
getSlideComponent라는 함수로 screenWitdh에 따라 적절한 캐러셀을 보여주려고 한다.
screenWidth가 1200 이하면 MO 버전으로, 그 이상이면 PC 버전의 캐러셀을 보여주려고 한다.
const getSlideComponent = () => {
if (screenWidth <= 1200) {
return slidesMO;
} else if (screenWidth > 1200) {
return slidesPC;
}
};
slidesMO, slidesPC는 모두 string[] 타입을 갖고 있다.
const slidesPC = [
`${import.meta.env.VITE_PUBLIC_URL}/src/assets/img/carousel/딸기_PC.jpg`,
`${import.meta.env.VITE_PUBLIC_URL}/src/assets/img/carousel/MD_PC.jpg`,
];
const slidesMO = [
`${import.meta.env.VITE_PUBLIC_URL}/src/assets/img/carousel/딸기_MO.jpg`,
`${import.meta.env.VITE_PUBLIC_URL}/src/assets/img/carousel/MD_MO.jpg`,
];
JSX 구문에 아래와 getSlideComponent를 실행 시켜 나온 slide를 보여주려고 한다.
{getSlideComponent().map(slide => (
<SwiperSlide key={slide}>
<SlideImg src={slide} />
</SwiperSlide>
))}
이 때 getSlideComponent에 에러가 발생했다.
Object is possibly 'undefined'.ts(2532)
📌 발생 이유
TS가 보기에 해당 객체나 변수가 undefined일 가능성이 있기 때문에 위와 같은 에러가 발생한다.
에러 메세지 밑을 보면 getSlideComponent의 반환값 유형이 string[]이거나 undefined로 정의되어 있다.
현재 화면 폭의 기준이 1200인데 코드를 수정하다 여기에 해당하는 슬라이드 배열이 없거나, slidesPC나 slidesMO를 수정하다 빈 배열이 되어 버리는 경우에 undefined가 될 수도 있다.
따라서 getSlideComponent를 실행시키면 무조건 string[]이 나온다는 것을 명시해주어야 한다.
또는 getSlideComponent의 실행값이 무조건 있다 (!undefined)라는 것을 명시해주면 된다.
☄️ 해결 방법
1번째 해결 방안
이 함수의 반환값은 string[]이며 해당하지 않을 경우 빈 배열을 반환하게 한다.
const getSlideComponent = (): string[] => {
if (screenWidth <= 1200) {
return slidesMO;
} else if (screenWidth > 1200) {
return slidesPC;
}
return [];
};
이 때 return []를 작성하지 않으면 새로운 에러를 발견하게 된다.
Function lacks ending return statement and return type does not include 'undefined'.
함수에 종료 반환문이 없고 반환 유형에 'undefined'이 포함되지 않습니다.
에러 메세지가 명확하기 때문에 이를 반대로 해주면 된다.
종료 반환문을 작성하고, 반환 유형에 undefined가 아닌 다른 값을 작성해준다.
2번째 해결 방법
반환하는 값이 항상 있다, 즉 undefined가 아니라고 non-null 단언 연산자를 사용하면 된다.
{getSlideComponent()!.map(slide => (
<SwiperSlide key={slide}>
<SlideImg src={slide} />
</SwiperSlide>
))}
두 해결 방법 모두 장단점이 있다.
1번째 해결 방법의 경우 반환 유형을 명시적으로 작성해서 코드의 가독성이 좀 더 좋고, 함수를 호출하는 곳에서도 반환값의 타입을 명확하게 알 수 있다. 그리고 TS가 함수의 반환값이 항상 정의되어 있다는 걸 알기 때문에 에러가 발생될 확률도 더 적을 것 같다.
2번째 해결 방법의 경우 1번에 비해 코드가 간단하다. 느낌표 하나만 쓰면 되니까...
하지만 1번째가 더 장점이 많고, 타입 강제를 남용하면 타입 안전성이 떨어질 수 있으므로 1번째 방법대로 코드를 수정했다. ✨
타입스크립트야 계속 친해지자...
'❔ TypeScript' 카테고리의 다른 글
[TypeScript] Geolocation API와 구글 맵 API를 사용한 역지오코딩 (0) | 2024.05.28 |
---|---|
[TypeScript] TanStack Query 사용 시 Type '{}' is not assignable to type 'ReactNode'. 에러 해결 (0) | 2024.05.12 |
[TypeScript] axios error 객체 처리하기 (0) | 2024.04.29 |
[TypeScript] yarn + Vite + TS로 웹 개발 시작하기 (5) | 2024.03.07 |