크고 작은 문제들/어려움

[TypeScript] 배열 요소에 대한 타입 추론

노새두마리 2023. 8. 17. 20:31

문제

React를 사용하면서 API 요청을 처리하는 훅을 정의하였습니다.

요청 함수로부터 얻은 데이터를 두 개의 state로 분리하여 배열 형태로 반환하고자 하였습니다.

함수 내부에서는 타입이 변수별로 정상적으로 추론되었지만, 실제 사용하고자 할 때 유니온 타입으로 추론되었습니다.

좌) 함수 내부, 우) 함수 호출


해결

함수 반환 타입을 명시하였습니다.

// const 함수명 = (인자): 반환 타입 => {...}

export const useGetPerformances = (...): [pageInfo: PageInfo | undefined, data: PerformanceType[]] => {
    const [pageInfo, setPageInfo] = useState<PageInfo>(); // undefined로 할당됩니다.
    const [data, setData] = useState<PerformanceType[]>([]);
    useEffect(() => {
        ...
        // 요청을 보낸 뒤 response data 안의 pageInfo 객체와 data를 나누어 state를 갱신하는 로직
        ...
        }, [...]);
        
    return [pageInfo, data];
}

함수 반환 타입을 명시하자 함수를 호출하는 부분에서도 타입을 정상적으로 인식하였습니다.


pageInfo state에 대하여 초깃값을 전달하지 않았으므로, 아래와 같이 배열의 형태 자체가 달라질 수도 있겠다고도 생각하였습니다.

이렇게 되지는 않습니다.

그러면 0번 index의 값이 경우에 따라서 pageInfo가 아닌 data가 될 수 있고, 유니온 타입으로 표시된 점도 충분히 이해할 수 있으니까요.

하지만, 그렇지는 않았습니다. pageInfo가 1번 index에 들어가는 경우는 없음에도 불구하고 배열의 1번 index에 해당하는 data의 타입 또한 유니온 타입으로 표시되었습니다.

또한, state 초깃값을 비워도 undefined 형태로 배열의 한 칸을 정상적으로 차지하는 것을 확인하였습니다.


그래도 왜 추론이 안 되는지 GPT에게 물어보았습니다. 답변은 다음과 같았습니다.

  • 타입이 서로 다른 요소가 배열 안에 있으면 유니온 타입으로 추론될 수 있다.
  • 함수 안에서 배열의 사용에 따라 요소의 타입이 달라질 수 있으면 유니온 타입으로 추론될 수 있다.

현 상황은 그나마 첫 번째 경우에 가까웠으며, 해결책으로는 다음을 제시하였습니다.

실제로 반환 타입을 명시함으로써 해결하였기도 했고, 함수 로직에 이상이 없는 게 확인되는 경우 빠르게 타입을 명시해서 해결하도록 해야겠습니다.