TypeScript
TypeScript 타입 에러가 늘어날 때 접근 방법
타입 안정성을 위해 점진적으로 타입 어노테이션을 강화할 때 체계적인 확인 절차.
타입 안정성을 높이려다 보면 기존 코드에서 타입 에러가 갑자기 많아 보일 수 있다. 문제를 크게 보면 모든 파일이 의심스러워지므로 작은 부분부터 차근차근 확인해야 한다.
문제의 범위 파악
먼저 컴파일 에러로 고민하지 말고 실제 런타임 동작을 본다. TypeScript 에러가 있어도 실제로는 코드가 정상 동작할 수도 있고, 타입만 맞으면 되는 경우도 있다.
npm run build
npx tsc --noEmit
NoEmit 옵션으로 타입 체크만 해서 에러 개수를 파악한다. 파일별 에러 분포를 보면 문제가 집중된 부분이 드러난다.
Optional과 Null 체크
TypeScript 에러의 대부분은 null | undefined 때문이다. 값이 없을 가능성이 있는데 타입이 non-nullable로 정의되었다는 뜻이다.
// 문제 상황
const name = user.name; // name이 string이라고 가정
const length = name.length; // 하지만 user.name이 undefined일 수 있음
// 해결
const name = user?.name;
const length = name?.length ?? 0;
API 응답, 쿼리 결과, props 등 외부에서 들어오는 값은 항상 undefined일 가능성을 염두에 두고 타입을 정의해야 한다.
타입 가드 활용
조건 분기에서 타입을 좀 더 구체적으로 좁혀줄 수 있다. 이렇게 하면 각 분기에서 불필요한 null 체크를 줄일 수 있다.
if (user && user.id) {
// 이 블록 안에서는 user.id가 항상 있다고 가정 가능
const userId: string = user.id;
}
// Array 필터링
const validUsers = users.filter((user): user is NonNullable<typeof users[number]> =>
user !== null
);
실제 응답과 타입 정의 비교
API 응답 타입을 정의했다면 실제 응답이 그 타입과 일치하는지 확인한다. 백엔드가 예상과 다른 구조를 반환할 수 있다.
- 브라우저 Network tab에서 실제 응답 JSON을 확인
- Postman이나 curl로 직접 요청해서 응답 본문을 비교
- 타입 정의와 실제 응답의 필드명, 자료형이 일치하는지 확인
단계적으로 any 제거하기
이미 있는 코드에 any가 많다면 한번에 모두 고치지 말고 단계적으로 진행한다. 먼저 중요한 부분부터 타입을 명시하고, 나머지는 차후 개선으로 미룰 수 있다.
// 이전
function process(data: any) {
return data.value + 1;
}
// 개선
interface ProcessData {
value: number;
}
function process(data: ProcessData) {
return data.value + 1;
}
빌드 후 확인
타입 에러를 수정한 후 실제 런타임 동작을 확인한다. 타입을 강화했다고 해서 기능이 바뀌지는 않지만, 빌드나 번들 크기가 변할 수 있으니 체크해야 한다.