자바스크립트 프로젝트 타입스크립트로 점진적 마이그레이션 하기

코드별로 우선순위를 설정해서 점진적으로 타입스크립트로 마이그레이션 하는 과정과 타입 생성 도구나 타입 선언만 추가해 작업 시간을 최소화

2024년 05월 05일

typescript

자바스크립트로 작성된 레거시 프로젝트를 유지보수하면서 고민했던 과정을 정리해보려고 합니다.

일정이 급했기 때문에 모든 코드를 타입스크립트로 마이그레이션 할 수는 없었고, 수정해야 하는 코드와 맞닿아 있는 코드부터 마이그레이션 작업을 시작했습니다.

1. 자바스크립트 프로젝트에 타입스크립트 세팅하기

타입스크립트 패키지를 설치 해줍니다. 기본적으로는 react 타입 패키지를 먼저 설치하고, 나중에 타입 패키지가 필요한 라이브러리가 있으면 그 때 마다 설치해서 사용했습니다.

yarn add -D typescript @types/react @types/react-dom

tsconfig.json에서는 아래 옵션을 주로 설정했습니다.

  • allowJs: true
    • 타입스크립트 파일을 자바스크립트 파일과 함께 사용하도록 허용했습니다
  • noImplicitAny: false
    • 마이그레이션 작업 초반에는 false로 설정해두고, 코드베이스가 안정화 되면 옵션을 활성화 하는 걸 목표로 두었습니다

프로젝트가 create-react-app으로 되어 있어 Adding TypeScript docs를 참고했습니다.

2. 자바스크립트 코드 타입스크립트로 마이그레이션하기

점진적으로 적용하는게 목표였기 때문에 어떤 코드부터 타입스크립트로 마이그레이션 할지 우선순위를 정하고 작업을 시작했습니다.

우선순위를 판단하는 기준은 아래와 같이 정했습니다.

  • 우선 순위가 높은 경우 🔼
    • 유지보수할 코드와 연결되어 있는 코드
    • 서버에서 가져오는 데이터거나, 전역 상태를 관리하는 코드
  • 우선 순위가 낮은 경우 🔽
    • 자바스크립트 파일이 너무 크거나, 캡슐화가 되어 있는 경우
    • 단순히 JSX 렌더링을 실행하는 컴포넌트

마이그레이션 작업양을 줄이기 위해서, 데이터를 기반으로 타입을 생성해주는 도구를 활용했고, 상황에 따라 .ts파일로 바꾸지 않고, 타입 선언(.d.ts)만 추가하기도 했습니다.

2.1 데이터를 기반으로 타입을 생성해주는 도구 활용

마이그레이션을 하다보면 선언해줘야 하는 타입이 굉장히 많기 때문에, 타입 생성 도구를 적극적으로 활용했습니다.

transform - json-to-typescript를 주로 사용했는데요, 코드를 실행시키면서 변수에 들어가는 데이터의 구조를 확인하고 이를 타입스크립트 타입으로 변경했습니다.

{
  "name": "John Doe",
  "age": 30,
  "address": {
    "city": "Somewhere",
    "state": "CA"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "123-456-7890"
    }
  ],
  "children": [
    {
      "name": "Jane Doe",
      "age": 10
    }
  ]
}

예를 들어 위 json 데이터를 넣으면 아래 타입을 반환합니다. 물론 데이터를 기반으로 생성하는 코드기 때문에 100% 사용할 수는 없어 필요한 부분만 가져다가 사용했습니다.

export interface Root {
  name: string;
  age: number;
  address: Address;
  phoneNumbers: PhoneNumber[];
  children: Children[];
}
 
export interface Address {
  city: string;
  state: string;
}
 
export interface PhoneNumber {
  type: string;
  number: string;
}
 
export interface Children {
  name: string;
  age: number;
}

2.2 .ts파일로 바꾸지 않고, .d.ts 파일로 타입 선언만 추가하기

.js 파일을 .ts 파일로 바꾸면 많은 타입 에러와 부딫칩니다. 가능하면 모든 타입 에러에 대응해서 타입스크립트 코드를 늘리는게 제일 베스트겠지만, .js로 작성되어 있는 파일이 너무 커서 대응하기가 힘들거나 캡슐화되어 외부에서는 맥락을 알 필요가 없는 로직인 경우에는 자바스크립트 파일을 유지하고, 타입만 추가로 선언해주었습니다.

이는 d.ts파일을 사용해서 타입을 선언할 수 있습니다. 타입을 선언하고자 하는 자바스크립트 파일이 있는 위치에 파일을 만들어주면 됩니다.

예를 들어 hello.js 라는 자바스크립트 파일에 타입 선언을 추가 하고 싶다면, hello.d.ts 파일을 만들어줍니다.

// hello.js
export function greet(name) {
  return `Hello, ${name}!`;
}
// hello.d.ts
export function greet(name: string): string;

이후 ./hello를 import 해서 사용하면 작성한 타입이 적용됩니다.

결론

타입스크립트 마이그레이션 작업에 시간이 부족해서, 코드별로 우선순위를 설정해서 어떤 코드부터 타입스크립트로 마이그레이션 할지 고민했습니다.

타입스크립트 타입 생성해주는 도구를 사용하고, 상황에 따라 타입스크립트 파일로 바꾸지 않고, 타입 선언만 추가해서 시간을 최소화 했습니다.