typeScript를 사용하다가 생긴 에러에 대해 이야기해보려고 한다.
아직 typeScript에 익숙하지 않아서 그런지 생각보다 비슷한 오류가 자주 나고 있는 듯 하다.
'Champion[] | undefined' 형식은 'Champion[]' 형식에 할당할 수 없습니다. 'undefined' 형식은 'Champion[]' 형식에 할당할 수 없습니다.
이 에러가 발생하는 이유와 해결 방법에 대해서 알아볼까 한다.
🤔 에러의 원인
TypeScript를 사용하다보면 자주 마주치는 오류 중 하나이고, 특히 API 호출 결과를 다룰 때 자주 발생한다고 한다.
TypeScript는 함수가 반환하는 값의 타입을 검사를 한다.
만약 `Champion[]` 타입을 반환할 것으로 예상하지만, `undefined`를 반환할 가능성이 있다면 오류를 나타낸다.
// ChampionsPage
export const ChampionsPage = async () => {
const data: Champion[] = await getChampionList();
return (
<>
<div>챔피온 목록</div>
...
<>
)
}
위 코드에서 `getChampionList` 함수가 `Champion[]` 타입의 데이터를 반환하겠지만, `catch`에서 값을 반환받고 있지 않기 때문에 `undefined`를 반환할 가능성도 있다.
// serverApi.ts
export const getChampionList = async () => {
try {
const version = await getLatestVersion();
const res = await fetch(
`https://ddragon.leagueoflegends.com/cdn/${version}/data/ko_KR/champion.json`,
{
next: {
revalidate: 86400,
},
}
);
const data = await res.json();
const champions: Champion[] = Object.values(data.data);
return champions;
} catch (error) {
console.log(error);
}
};
즉, 성공적으로 데이터를 불러오면 `Champion[]`을 반환 / 오류가 발생하면 `undefined`를 반환
따라서 이 함수는 `Champion[] | undefined` 타입을 반환하는 것으로 간주를 하게 된다.
이를 해결하기 위해 2가지 방법을 정리해보았다.
💡 해결 방법 1 : undefined 처리 추가
`undefined` 처리를 명시적으로 작성하여 해결한다.
함수의 반환타입 자체를 `Champion[] | undefined` 타입으로 명시하고, 데이터를 사용하는 쪽에서 `undefined` 일 가능성을 처리하면 된다.
// ChampionsPage
export const ChampionsPage = async () => {
const data: Champion[] | undefined = await getChampionList();
if (!data) {
return <div>챔피언 목록을 불러오는 데 실패했습니다.</div>;
}
return (
<>
<div>챔피언 목록</div>
...
</>
);
};
그리고 `if문`을 통해 `data`가 없는 경우를 처리해주는데 그렇지 아니하면 return 이하에서 사용하는 data에서 오류가 날 수 있다.
💡 해결 방법 2 : 함수에서 처리
`undefined`를 반환하지 않도록 `getChampionList` 함수에서 기본값으로 `catch` 이하에 `빈배열[]` 을 추가하는 것이다.
// serverApi.ts
export const getChampionList = async (): Promise<Champion[]> => {
try {
const version = await getLatestVersion();
const res = await fetch(
`https://ddragon.leagueoflegends.com/cdn/${version}/data/ko_KR/champion.json`,
{
next: {
revalidate: 86400,
},
}
);
const data = await res.json();
const champions: Champion[] = Object.values(data.data);
return champions;
} catch (error) {
console.log(error);
return []; // 오류 발생 시 빈 배열을 반환(추가)
}
};
이렇게 작성하면 호출하는 페이지에서 별도의 오류 처리를 할 필요가 없어진다.
// ChampionsPage
export const ChampionsPage = async () => {
const data: Champion[] = await getChampionList();
return (
<>
<div>챔피언 목록</div>
...
</>
);
};
👍 결론
TypeScript에서 `undefined` 타입을 처리하는 것은 안전한 코드 작성에서 필수적 부분이다.
API 요청이나 비동기 작업에서는 `undefined`가 발생할 가능성이 크기 때문에 이를 완벽하게 처리해주어야 한다.
그리고 2가지 방법을 이야기했지만
1. 코드 간결성 - 데이터 사용하는 페이지에서 일일이 undefined를 처리하지 않을 수 있어서
2. 예상 가능한 반환값 지정 용이 - Champion[]을 반환하겠다는 보장이 있었음
등을 이유로 2번째 방법을 사용하게 되지 않을까 싶다.
TypeScript 사용에 익숙해지자... ㅎㅎ
'프론트엔드 > TypeScript' 카테고리의 다른 글
타입스크립트 - TodoList 만들며 정리 (0) | 2024.09.25 |
---|