"타입 검사에만 필요한 이름이라면, 실행할 JavaScript에는 남기지 않겠다고 말해 줘."
타입 전용 가져오기
import type { User } from './types.js'는 User를 타입 위치에서만 쓸 수 있게 하고 출력 JavaScript에서는 import를 지워. 파일을 실행하지 않아도 되는 순수한 타입 의존성이라는 뜻이 코드에 드러나지.
하나의 import에서 값과 타입을 섞어야 한다면 import { createUser, type User } from './user.js'처럼 이름별로 표시할 수 있어. 값 자리에 필요한 대상을 import type으로 가져오면 컴파일러가 거절하므로 잘못된 경계를 일찍 발견해.
verbatimModuleSyntax가 주는 압력
verbatimModuleSyntax를 켜면 type 표시가 없는 import와 export를 가능한 그대로 남기고, 타입 전용으로 표시한 것만 제거해. 컴파일러의 추측에 의존하던 import 생략 규칙이 단순해져서 소스와 출력의 관계도 읽기 쉬워져.
대신 CommonJS 설정에 ESM 문법을 어설프게 섞은 구성도 더 빨리 드러난다. 오류를 우회하려고 플래그를 끄기보다 패키지의 실제 모듈 형식과 TypeScript 설정이 맞는지 확인해.
실행 부작용과 순환 참조
값 import는 대상 모듈을 실행할 수 있지만 타입 import는 그렇지 않아. 클래스 등록이나 전역 초기화를 import 부작용에 기대는 코드에서는 둘의 차이가 실제 동작을 바꿔. 부작용이 필요하면 import './register.js'처럼 의도를 별도로 드러내.
타입 전용 import는 순환 의존성의 런타임 고리를 줄이는 데도 도움을 줘. 하지만 설계상 서로를 알아야 하는 두 계층을 자동으로 바로잡지는 않아. 공통 타입을 중립 모듈로 옮기는 것이 더 명확할 수 있어.
이름별로 값과 타입 import를 섞는 문법은 TypeScript 4.5부터 쓸 수 있어. TypeScript 5.0에서 추가된 verbatimModuleSyntax를 켜면 import type과 export type만 지워지고 나머지는 유지되어 출력 규칙이 예측 가능해져.
import type은 최적화 표지가 아니라 의존성의 종류를 밝히는 계약이야. 컴파일 때만 필요한지, 모듈 실행까지 필요한지 소스에서 구분해.