TypeScript 6.0이 3월 말에 정식 출시됐다. 새 기능? 거의 없다. 대신 tsconfig.json에서 쓰던 옵션 상당수에 deprecation 경고가 뜬다. 이게 왜 중요하냐면, 6.0이 JavaScript로 작성된 마지막 TypeScript 컴파일러이기 때문이다. 다음 메이저 버전은 Go로 재작성된 완전히 다른 엔진이고, 지금 뜨는 경고를 무시하면 그때 한꺼번에 터진다.
ES5 타깃, AMD 모듈 — 전부 퇴장
target: "es5" 아직 쓰고 있었다면 이제 빨간 줄이 그인다. ES3과 ES5 타깃이 deprecated됐고, 최소 지원이 ES2015로 올라갔다. 2026년에 ES5 트랜스파일이 필요한 환경이 있다면 그건 TypeScript 문제가 아니라 프로덕트 문제다.
모듈 시스템도 정리됐다. module: "amd", "umd", "systemjs" 전부 제거. ESM이 이긴 전쟁은 5년 전에 끝났는데, tsconfig만 과거에 머물러 있던 셈이다. 이제 선택지는 둘이다 — 번들러 쓰면 "bundler", Node 직접 실행이면 "nodenext".
moduleResolution: "node"도 퇴장한다. 공식 명칭은 node10이었는데 대부분이 그냥 "node"라고 써왔을 거다. "classic"은 당연히 함께 사라진다. 그리고 baseUrl — 경로 매핑 때문에 거의 모든 프로젝트가 설정해뒀을 텐데, deprecated다. paths 항목에 기본 경로를 직접 넣으면 된다.
ignoreDeprecations — 유예 기간이지 면제가 아니다
마이그레이션이 당장 어려운 팀을 위해 탈출구가 하나 있다:
{
"compilerOptions": {
"ignoreDeprecations": "6.0"
}
}
경고가 사라진다. 깔끔하다. 하지만 TypeScript 7.0에서는 이 옵션 자체가 인식되지 않는다. 지금 눈 감고 넘어간 경고가 전부 hard error로 돌아온다. 이걸 "마이그레이션 완료"라고 착각하는 팀이 분명히 나올 텐데, 빚을 갚은 게 아니라 만기를 연장한 것이다.
6.0 건너뛰고 7.0으로 바로 올리려는 계획도 비추천한다. 자동 마이그레이션 도구가 6.0 기준으로 만들어져 있고, 7.0에서는 deprecation 경고 없이 바로 에러가 뜨기 때문에 디버깅이 훨씬 고통스럽다. 순서대로 가는 게 맞다.
자동 도구는 이거다:
npx @andrewbranch/ts5to6
target 교체, module 교체, baseUrl 제거 같은 기계적 변경을 대부분 처리해준다. 돌린 다음 npx tsc --noEmit으로 확인. 모노레포라면 패키지별로 돌려야 하니까 시간을 좀 잡아야 한다.
89초가 8.7초가 된다 — tsgo의 실측 수치
TypeScript 7.0의 Go 컴파일러, 코드네임 tsgo. 올해 1월에 안정 버전이 나왔고, 벤치마크 수치가 좀 비현실적이다:
| 프로젝트 | tsc (TS 6) | tsgo (TS 7) | 배수 |
|---|---|---|---|
| VS Code (150만 줄) | 89초 | 8.7초 | 10.2× |
| Sentry | 133초 | 16초 | 8.3× |
| 타입 체킹 단독 | — | — | ~30× |
메모리도 2.9배 덜 먹는다. 다만 10만 줄 이하 프로젝트에서는 체감이 2-5배 수준이다. 대형 모노레포에서 효과가 극대화되는 구조인데, Go 고루틴으로 파일 단위 병렬 타입 체킹을 하기 때문이다. JavaScript 싱글 스레드에서는 구조적으로 불가능했던 것.
언어 자체는 바뀌지 않았다. tsgo는 새 언어가 아니라 더 빠른 엔진이다. 에디터 통합(VS Code의 TS 서버)은 아직 옵트인이고, 기능 동등성이 확보되면 기존 서비스를 교체할 예정.
당장 해야 할 것
npx @andrewbranch/ts5to6한 번 돌리기ignoreDeprecations로 임시 회피하더라도 마이그레이션 티켓은 만들어 두기CI에서 tsgo로
--noEmit돌려서 어디가 터지는지 미리 파악
에디터를 tsgo 기반으로 바꾸거나, CI 전체를 한 번에 전환하는 건 아직 이르다.
.d.ts가 달라지는 함정
라이브러리 제작자라면 하나 더. TS 6.0에 --stableTypeOrdering 플래그가 추가됐다.
TypeScript는 타입을 만나는 순서대로 내부 ID를 부여하고, 유니온 타입을 그 순서로 정렬한다. TS 7.0은 병렬 체킹을 하니까 파일 방문 순서가 매 빌드마다 다를 수 있고, string | number가 어떤 빌드에서는 number | string으로 뒤집힌다. 타입 호환성에는 영향이 없지만, 자동 생성된 선언 파일에 불필요한 diff가 난무하게 된다.
--stableTypeOrdering을 켜면 6.0의 정렬 방식이 7.0과 동일해져서, 이행 시 diff 노이즈를 미리 잡을 수 있다. 앱 개발자는 신경 안 써도 되지만, npm에 .d.ts를 배포하는 사람이라면 지금 켜두는 게 낫다.