TypeScript 3.8 업그레이드 후 import type 적용기

배경

재택근무 전환 후 첫 주에 프로젝트 TypeScript 버전을 3.7에서 3.8로 올렸다. 3.8의 주요 기능 중 import type 구문이 눈에 띄어 적용해보기로 했다.

기존에는 타입과 값을 구분 없이 import 했는데, 이게 가끔 순환 참조 문제를 일으키거나 번들러가 불필요한 모듈을 포함시키는 경우가 있었다.

import type이 필요한 이유

// 기존 방식
import { User } from './types';
import { fetchUser } from './api';

// 새 방식
import type { User } from './types';
import { fetchUser } from './api';

import type을 사용하면 해당 import가 타입 전용임을 명시할 수 있다. 컴파일 후 JavaScript에서 완전히 제거되므로 런타임 번들에 영향을 주지 않는다.

적용 과정

프로젝트 전체에 ESLint 규칙을 추가했다.

{
  "@typescript-eslint/consistent-type-imports": [
    "error",
    { "prefer": "type-imports" }
  ]
}

약 200개 파일에서 자동 수정이 적용됐다. 대부분 인터페이스, 타입 별칭, enum import가 대상이었다.

주의사항

React 컴포넌트는 타입으로만 사용되더라도 import type을 쓰면 안 된다.

// ❌ 잘못된 예
import type { FC } from 'react';

// ✅ 올바른 예  
import { FC } from 'react';

FC는 타입이지만 react 모듈 자체는 값으로도 필요하기 때문이다.

결과

번들 크기가 약 3KB 줄었다. 크진 않지만 타입 임포트가 명확해져서 코드 가독성이 개선됐다. 특히 타입만 export하는 파일들에서 의도가 더 명확해진 느낌이다.

팀원들과 컨벤션으로 정하고 ESLint로 강제하기로 했다.