1️⃣ 함수 문장을 함수 표현식으로 바꾸고 함수 2️⃣ 전체에 타입(typeof fetch)을 적용한다.
→ 타입스크립트가 input과 init의 타입을 추론할 수 있게 해준다.
3️⃣ checkedFetch의 반환 타입을 보장하며, fetch와 동일하다. (throw 대신 return을 사용했다면, 타입스크립트가 실수를 잡아낸다.)
const checkedFetch: typeof fetch = async (input, init) => {
// ~~~~~~~~~~~~
// 'Promise<Response | HTTPError>' is not assignable to 'Promise<Response>'
// Type 'Response | HTTPError' is not assignable to type 'Response'
const response = await fetch(input, init);
if (!response.ok) {
return new Error('Request failed: ' + response.status);
}
return response;
}
⭐️ 정리
함수의 매개변수에 타입을 선언하는 것보다 함수 표현식 전체 타입을 정의하는 것이 코드도 간결하고 안전하다. 다른 함수의 시그니처와 동일한 타입을 가지는 새 함수를 작성하거나, 동일한 타입 시그니처를 가지는 여러 개의 함수를 작성할 때는 매개변수의 타입과 반환 타입을 반복해서 작성하지 말고, 함수 전체의 타입 선언을 적용해야 한다.
📍 요약
매개변수나 반환 값에 타입을 명시하기보다는 함수 표현식 전체에 타입 구문을 적용하는 것이 좋다.
만약 같은 타입 시그니처를 반복적으로 작성한 코드가 있다면 함수 타입을 분리해 내거나 이미 존재하는 타입을 찾자. 라이브버리를 직접 만든다면 공통 콜백에 타입을 제공해야 한다.