API
TypeScript 타입을 API 스키마와 맞추는 방법
API 응답 타입이 실제 데이터와 안 맞으면 런타임에 버그가 터진다. 처음부터 맞추는 게 핵심이다.
TypeScript를 쓸 때 가장 흔한 실수는 타입 정의와 실제 API 응답이 어긋나는 거다. 개발할 땐 문제가 없다가 운영 데이터를 만나면 예상 밖의 필드가 있거나 타입이 다를 수 있다.
먼저 실제 API 응답 확인하기
타입을 정의하기 전에 API가 실제로 뭘 반환하는지 봐야 한다.
curl -s 'https://api.example.com/items?page=1' | jq '.'
jq로 보면 필드 구조와 각 값의 타입이 한눈에 들어온다. 특히 null 가능성, 배열인지 객체인지, 문자열인지 숫자인지 꼭 확인한다.
타입 정의 체크리스트
실제 응답을 본 뒤에 타입을 정의한다:
- 모든 필드를 포함했는가
- 옵셔널(
?)과 필수 필드를 올바르게 구분했는가 null가능한 필드는| null을 붙였는가- 날짜 문자열은
string아니면Date로 할 건가 - 열거형은 리터럴 타입 유니온으로 정의했는가
type Item = {
id: string;
name: string;
price: number;
tags: string[];
createdAt: string; // ISO 8601
updatedAt?: string;
deletedAt: string | null;
};
런타임에 타입 검증하기
TypeScript는 컴파일할 때만 타입을 확인한다. 런타임에는 아무것도 확인 안 하기 때문에 서버에서 예상 밖의 데이터가 올 수 있다. 실제 사용하는 곳에서 타입 가드를 넣으면 좋다.
function isItem(obj: unknown): obj is Item {
return (
typeof obj === 'object' &&
obj !== null &&
'id' in obj &&
'name' in obj &&
'price' in obj
);
}
const response = await fetch('/api/items');
const data = await response.json();
if (isItem(data)) {
// data의 타입이 Item임을 보장
console.log(data.name);
}
API 변경에 대비하기
API가 업데이트되면서 새 필드가 추가되거나 사라질 수 있다. 타입을 정의할 때부터 앞으로의 변화를 고려하면 유지보수가 쉬워진다.
// 나쁜 예: 빠진 필드 발견 시 모든 코드에서 에러
type Item = {
id: string;
name: string;
};
// 좋은 예: 알 수 없는 필드는 무시
type Item = {
id: string;
name: string;
[key: string]: unknown;
};
타입과 API 응답을 맞추는 건 시간이 걸리지만, 나중의 디버깅 시간을 크게 줄인다.