기존 JavaScript 프로젝트에 TypeScript 점진적으로 도입하기
배경
작년부터 운영 중인 React 프로젝트에 TypeScript를 도입하기로 했다. 컴포넌트가 100개가 넘는 상황에서 한 번에 전환하는 건 무리였고, 점진적 마이그레이션 전략을 택했다.
초기 설정
먼저 tsconfig.json을 생성하고 기존 JS 파일과 공존할 수 있도록 설정했다.
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"lib": ["dom", "es2015"],
"jsx": "react",
"allowJs": true,
"checkJs": false,
"strict": false,
"esModuleInterop": true
},
"include": ["src/**/*"]
}
allowJs: true로 JS와 TS 파일을 섞어 쓸 수 있게 했다. strict: false로 시작해서 타입 에러에 막히지 않도록 했다.
마이그레이션 순서
- 유틸 함수부터 시작 - 의존성이 적고 테스트하기 쉬움
- 타입 정의 파일 작성 - 자주 쓰는 도메인 모델부터
- 신규 컴포넌트는 무조건 TS로 작성
- 기존 컴포넌트는 수정할 때 TS로 전환
// types/user.ts
export interface User {
id: number;
email: string;
name: string;
createdAt: string;
}
export interface ApiResponse<T> {
data: T;
error?: string;
}
겪은 문제
1. any 남발
초기엔 타입을 모르는 곳마다 any를 썼다. 점차 unknown으로 바꾸거나 제대로 된 타입을 정의하는 방향으로 개선 중이다.
2. 서드파티 라이브러리
@types 패키지가 없는 라이브러리들이 있었다. d.ts 파일을 직접 작성하거나, 일단 declare module로 우회했다.
// types/custom.d.ts
declare module 'some-library' {
export function someFunc(param: string): void;
}
현재 상태
전체 파일의 약 30%를 TS로 전환했다. 타입 체크 덕분에 props 전달 실수나 undefined 에러를 몇 건 사전에 잡았다. 아직 strict: true는 부담스럽지만, 내년 초쯤엔 전환 완료가 목표다.