TypeScript 타입 가드로 API 응답 안전하게 다루기
문제 상황
외부 결제 API를 연동하면서 응답 데이터의 타입 안정성이 보장되지 않는 문제가 있었다. interface로 타입을 정의했지만, 실제 런타임에서는 예상과 다른 데이터가 들어올 수 있었다.
interface PaymentResponse {
status: 'success' | 'failed';
amount: number;
transactionId: string;
}
const response = await fetch('/api/payment');
const data: PaymentResponse = await response.json(); // 타입 단언만으로는 불충분
타입 가드 도입
타입 가드 함수를 만들어 런타임에 실제 데이터 구조를 검증하도록 했다.
function isPaymentResponse(data: any): data is PaymentResponse {
return (
typeof data === 'object' &&
data !== null &&
(data.status === 'success' || data.status === 'failed') &&
typeof data.amount === 'number' &&
typeof data.transactionId === 'string'
);
}
const response = await fetch('/api/payment');
const data = await response.json();
if (isPaymentResponse(data)) {
// 이 블록 안에서는 data가 PaymentResponse 타입으로 추론됨
console.log(data.transactionId);
} else {
throw new Error('Invalid payment response');
}
결과
타입 가드를 통해 컴파일 타임과 런타임 모두에서 타입 안정성을 확보했다. API 스펙 변경이나 예상치 못한 응답에도 빠르게 대응할 수 있게 되었다.
유틸리티 함수로 분리해 다른 API 응답 처리에도 동일한 패턴을 적용 중이다.