프로젝트에 TypeScript 도입하며 겪은 시행착오
배경
작년 하반기부터 TypeScript 도입을 검토했고, 올해 초 드디어 실무에 적용하기 시작했다. 3만 줄이 넘는 JavaScript 코드베이스를 한 번에 마이그레이션할 수는 없어서 점진적 도입 전략을 택했다.
초기 세팅
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": ["es2017", "dom"],
"allowJs": true,
"checkJs": false,
"jsx": "react",
"strict": false,
"esModuleInterop": true
}
}
allowJs를 켜고 strict를 끈 상태로 시작했다. 기존 JS 파일과 새로운 TS 파일이 공존할 수 있도록 했다.
겪은 문제들
1. any의 유혹
처음엔 타입 에러가 나면 any로 때우는 경우가 많았다. 특히 서드파티 라이브러리 타입 정의가 없을 때 더 그랬다.
const data: any = await fetchData();
// 이러면 타입스크립트를 쓰는 의미가...
지금은 최소한 unknown을 쓰거나, 제대로 된 인터페이스를 정의하려 노력 중이다.
2. 타입 정의 파일의 부재
사내에서 만든 유틸리티 라이브러리들은 당연히 타입 정의가 없었다. .d.ts 파일을 직접 작성해야 했는데, 처음엔 제대로 된 타입을 만드는 게 어려웠다.
// utils.d.ts
declare module 'internal-utils' {
export function formatDate(date: Date): string;
export function parseQuery(query: string): object; // object는 너무 광범위
}
3. 팀원들의 러닝커브
제네릭, 유니온 타입, 인터페이스 등 개념이 익숙하지 않은 팀원들이 있었다. 코드 리뷰 시간이 늘어났고, 타입 에러 해결에 시간을 많이 썼다.
현재 상태
신규 컴포넌트는 모두 TypeScript로 작성하고 있다. 레거시 코드는 수정할 일이 있을 때마다 조금씩 마이그레이션 중이다. 아직 갈 길이 멀지만, 런타임 에러가 확실히 줄어든 것을 체감하고 있다.
다음 목표는 strict 모드를 켜는 것이다. 지금 켜면 에러가 수백 개 쏟아질 것 같지만, 언젠가는 해야 할 일이다.