TypeScript 4.0 적용 후기 - 재택 근무 중 레거시 코드베이스 마이그레이션
배경
재택 근무가 시작된 후 3개월간 진행했던 레거시 프로젝트의 TypeScript 마이그레이션을 완료했다. 2년 전 작성된 JavaScript 코드베이스(약 3만 줄)를 TypeScript 4.0으로 전환하는 작업이었다.
적용 전략
한 번에 전환하는 것은 리스크가 컸기 때문에 점진적 접근을 택했다.
allowJs,checkJs옵션으로 시작- 핵심 유틸리티 함수부터
.ts전환 - API 타입 정의 작성
- 컴포넌트 단위로 순차 전환
// 초기 tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"allowJs": true,
"checkJs": false,
"strict": false,
"noImplicitAny": false
}
}
마주한 문제들
1. 암묵적 any 남발
레거시 코드에서 가장 많이 발견된 패턴이었다. API 응답 타입이 정의되지 않아 모든 곳에서 any로 추론되었다.
// Before
const fetchUser = async (id) => {
const res = await api.get(`/users/${id}`);
return res.data; // any
};
// After
interface User {
id: number;
email: string;
role: 'admin' | 'user';
}
const fetchUser = async (id: number): Promise<User> => {
const res = await api.get<User>(`/users/${id}`);
return res.data;
};
2. 타입 가드 필요성
런타임 체크가 없던 코드에 타입 가드를 추가해야 했다.
function isErrorResponse(res: unknown): res is { error: string } {
return typeof res === 'object' && res !== null && 'error' in res;
}
3. 빌드 시간 증가
초기에는 빌드 시간이 2배 가까이 증가했다. skipLibCheck: true 추가와 incremental 컴파일로 개선했다.
결과
- 런타임 에러 30% 감소 (프로덕션 로그 기준)
- IDE 자동완성으로 개발 속도 체감상 향상
- 리팩토링 시 타입 에러로 사이드 이펙트 사전 발견
재택 근무 중이라 커뮤니케이션 오버헤드가 걱정됐는데, 타입 정의가 문서 역할을 해서 오히려 도움이 되었다. 다음 프로젝트는 처음부터 TypeScript로 시작할 예정이다.