TypeScript 3.5 도입 후기: 점진적 마이그레이션 전략

배경

회사 프로젝트가 3만 줄 규모의 JavaScript 코드베이스였다. 타입 관련 버그가 반복되면서 TypeScript 도입이 결정됐고, 내가 마이그레이션을 담당하게 됐다.

빅뱅 방식은 리스크가 컸다. 점진적 마이그레이션 전략을 선택했다.

초기 설정

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "allowJs": true,
    "checkJs": false,
    "strict": false,
    "noImplicitAny": false
  }
}

allowJs로 JS와 TS를 혼용할 수 있게 했다. strict 옵션들은 나중에 단계적으로 활성화할 계획이었다.

마이그레이션 순서

  1. 유틸리티 함수부터 시작
  2. 타입 정의 파일 작성 (.d.ts)
  3. 컴포넌트 레이어 변환
  4. 비즈니스 로직 변환

가장 의존성이 적은 유틸부터 변환했다. 다른 파일들이 점차 타입 혜택을 받을 수 있었다.

주요 이슈

any 남발 문제

처음엔 빠른 마이그레이션을 위해 any를 많이 썼다. 결국 기술 부채가 됐다.

해결책: unknown을 쓰고 타입 가드로 좁히는 방식으로 변경했다.

function parseData(data: unknown) {
  if (typeof data === 'string') {
    return JSON.parse(data);
  }
  return data;
}

서드파티 라이브러리 타입

오래된 라이브러리들은 타입 정의가 없었다. @types를 찾거나 직접 작성해야 했다.

// types/old-library.d.ts
declare module 'old-library' {
  export function doSomething(value: string): number;
}

결과

3개월간 70% 정도 마이그레이션을 완료했다. 타입 관련 버그가 눈에 띄게 줄었고, IDE 자동완성으로 생산성도 올랐다.

완전한 마이그레이션보다 실용적인 타입 커버리지를 목표로 했던 게 좋은 선택이었다.

TypeScript 3.5 도입 후기: 점진적 마이그레이션 전략