JavaScript 프로젝트에 TypeScript 점진적으로 도입하기

배경

회사 프로젝트가 JavaScript로만 작성되어 있었는데, 코드베이스가 커지면서 런타임 에러가 잦아졌다. 특히 API 응답 구조가 변경되거나 함수 인자를 잘못 넘기는 실수가 반복됐다. TypeScript 도입을 검토했지만, 한 번에 전환하기엔 규모가 커서 점진적 마이그레이션 전략을 택했다.

설정

tsconfig.json에서 핵심은 allowJscheckJs 옵션이었다.

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "allowJs": true,
    "checkJs": false,
    "jsx": "react",
    "strict": false,
    "esModuleInterop": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

allowJs를 켜면 .js.ts 파일을 함께 빌드할 수 있다. strict는 나중에 켜기로 했다.

진행 방식

  1. 유틸 함수부터 .ts로 전환
  2. 타입 정의가 명확한 모듈 우선 작업
  3. API 응답 인터페이스 작성
// types/api.ts
export interface User {
  id: number;
  name: string;
  email: string;
  createdAt: string;
}

export interface ApiResponse<T> {
  data: T;
  status: number;
  message?: string;
}

기존 JavaScript 파일에서도 import해서 JSDoc으로 타입 힌트를 줄 수 있었다.

// legacy.js
/** @type {import('./types/api').User} */
const user = fetchUser();

마주친 문제

  • 써드파티 라이브러리 타입 정의 부족: @types/ 패키지가 없으면 declare module로 임시 처리
  • any 남발 유혹: 급할 땐 any 쓰되, TODO 주석 남겨서 나중에 개선
  • 빌드 속도: ts-loader 대신 babel-loader + @babel/preset-typescript 조합이 더 빨랐다

결과

2개월간 핵심 모듈 30% 정도를 TypeScript로 전환했다. 런타임 에러가 눈에 띄게 줄었고, IDE 자동완성 품질이 올라가 개발 속도도 개선됐다. 남은 코드는 내년 상반기까지 순차적으로 전환할 예정이다.

JavaScript 프로젝트에 TypeScript 점진적으로 도입하기