tsc와 tsc6로 TypeScript 7 업그레이드 검증하기
좋아요 · 후기 쓰기
이 글의 목차 · 9개 항목
TypeScript 7은 TypeScript 6과 나란히 실행된다. 두 컴파일러를 함께 사용해 에이전트의 편법을 잡아내자. 더 느슨한 tsconfig, 새로 추가된 @ts-ignore, 바뀐 JS까지.

에이전트는 업그레이드가 끝났다고 말한다. package.json에는 TypeScript 7이 들어 있고, npx tsc는 종료 코드 0으로 조용히 끝나며, 터미널의 요약은 깔끔한 변경 로그처럼 보인다. baseUrl이 제거되었고, 모듈 해석은 nodenext로 이동했으며, 타입 오류는 수정되었다고 한다.
종료 코드 0은 컴파일러가 만족했다는 뜻일 뿐이다. 그것이 어떤 방식으로 만족했는지는 알려주지 않는다. “tsc가 통과하게 만들어라”를 목표로 움직이는 에이전트는 깨끗한 실행을 얻기 위한 값싼 편법이 있다. strict를 끄고, skipLibCheck를 켜고, include에서 폴더 하나를 빼고, 경고가 난 모든 줄 위에 @ts-expect-error를 붙이면 된다. 이 각각은 빌드를 초록색으로 바꾼다. 하지만 그 어느 것도 업그레이드는 아니다.
이 업그레이드에는 심판이 하나 더 붙어 있다. TypeScript 7.0은 2026년 7월 8일에 출시되었고, Go 기반 네이티브 컴파일러가 일반 tsc로 설치된다. 같은 공지에는 "tsc6"라는 실행 파일을 제공하는 호환성 패키지 @typescript/typescript6도 언급되어 있다. 한 저장소 안에, 서로 일치해야 하는 두 컴파일러가 있는 셈이다. 그러면 Claude Code든 Codex든, 에이전트가 둘러댈 수 없는 검증 수단이 생긴다.
TypeScript 7에서 무엇이 바뀌고, 아직 무엇을 할 수 없는가
가장 큰 화제는 속도다. VS Code 코드베이스에서 릴리스 글은 전체 빌드 시간이 6.0의 125.7초에서 7.0의 10.6초로 줄었다고 보고한다. 또한 7.0은 기본적으로 4개의 워커로 타입 검사를 수행하며, --checkers로 조절할 수 있다.
에이전트에게 중요한 부분은 호환성 약속이다. 해당 글은 7.0이 “TypeScript 6.0의 타입 검사 및 명령줄 동작과 호환되도록 만들어졌다”고 말하며, stableTypeOrdering 플래그가 켜져 있고 ignoreDeprecations가 설정되지 않은 상태에서 TypeScript 6.0으로 “깨끗하게 컴파일되는” 코드는 “TypeScript 7.0에서도 동일하게 컴파일되어야 한다”고 설명한다. 이 조건을 두 번 읽어야 하는 이유는, 그것이 업그레이드의 전부이기 때문이다. 작업은 7.0의 규칙 아래에서 프로젝트를 6.0 기준으로 깨끗하게 만드는 것이다. 패키지를 바꾸는 것은 맨 마지막의 쉬운 단계다.
그 규칙들은 여러 기능을 없앤다. 같은 글에 따르면 target: es5와 downlevelIteration은 사라졌고, node/node10과 classic 모듈 해석도 사라졌으며, amd, umd, systemjs, none 모듈 형식도 없어졌고, baseUrl도 사라졌으며, esModuleInterop, allowSyntheticDefaultImports, alwaysStrict는 더 이상 false로 설정할 수 없다.
TypeScript 6.0은 이미 이 모든 것에 대해 경고했으며, 빠져나갈 길도 제공했다. 6.0 발표 글은 이러한 사용 중단 경고는 tsconfig에 "ignoreDeprecations": "6.0"을 설정하면 무시할 수 있다고 말하며, 같은 문장 안에서 “TypeScript 7.0은 이러한 사용 중단 옵션을 지원하지 않을 것”이라고 밝힌다. tsconfig의 그 한 줄은 마이그레이션에서 가장 유혹적인 지름길이다. 아무것도 고치지 않고도 6.0 경고를 사라지게 만들기 때문이다.
그리고 한계가 온다. 릴리스 글은 “TypeScript 7.0은 여기 있지만, API는 포함되지 않는다”고 말한다. typescript-eslint 같은, 코드에서 컴파일러를 직접 구동하는 도구들은 여전히 6.0이 필요하다. 또한 글은 Vue, MDX, Astro, Svelte 워크플로는 당분간 6.0을 유지할 것으로 예상한다고 적고, Angular 프로젝트는 에디터에서는 6.0을, 명령줄에서는 7.0의 tsc를 사용할 수 있다고 말한다. 새 API는 7.1에서 도입될 예정이다. 반복 계획은 원래 안정판을 2026년 11월 24일로 잡았고, 9월 1일에는 팀이 베타를 약 2주 앞당길 가능성을 검토하고 있다고 밝혔다.
그러므로 오늘날 대부분의 프로젝트에서 최종 상태는 두 컴파일러를 나란히 설치하는 것이다. 릴리스 글은 바로 그 용도로 npm 별칭을 권장한다:
{ "devDependencies": { "@typescript/native": "npm:typescript@^7.0.2", "typescript": "npm:@typescript/typescript6@^6.0.2" }}이렇게 하면 npx tsc는 7.0이 되고 npx tsc6는 6.0이 되며, typescript를 import하는 모든 것은 계속 6.0 API를 받는다. 어차피 tsc6가 필요하다. 그러니 그 검증을 에이전트 평가에 활용하면 된다.

Step 1: 에이전트를 위한 worktree와 계약
이미 TypeScript 6.0을 사용 중인 프로젝트에서 시작합니다. 릴리스 글에서는 먼저 이 작업을 권장하며, 그렇게 하면 비교 기준이 되는 베이스라인이 믿을 수 있는 하나의 tsc가 됩니다.
에이전트가 시작하기 전에 당신이 먼저 결정해야 할 것이 하나 있습니다. TypeScript 6.0에서는 strict의 기본값이 true로 바뀌었기 때문에, 이를 한 번도 설정하지 않은 프로젝트는 이미 그 변경 사항을 받아들인 상태였습니다. 이전 동작을 원한다면 main의 tsconfig에 직접 "strict": false를 적어 두세요. 그러면 에이전트가 당신의 코드베이스가 strict인지 아닌지를 결정하는 주체가 되지 않습니다.
에이전트에게 별도의 git worktree를 주면, 업그레이드는 분리된 폴더의 브랜치에서 진행되고 현재 체크아웃은 그대로 유지됩니다:
git worktree add -b ts7-upgrade ../app-ts7cd ../app-ts7claude # or: codexClaude Code는 워크플로 문서에서 보여 주듯 claude --worktree로 worktree를 직접 만들 수도 있습니다. 어느 쪽이든 첫 프롬프트는 아래 단축키들이 포함된 계약입니다:
Upgrade this repo to TypeScript 7.0 and keep 6.0 beside it:"@typescript/native": "npm:typescript@^7.0.2" and"typescript": "npm:@typescript/typescript6@^6.0.2".Remove tsconfig options TypeScript 7 no longer supports andfix what breaks. Both `npx tsc --noEmit` and`npx tsc6 --noEmit` must pass.Do not: set strict or any strict flag to false, addskipLibCheck, set ignoreDeprecations, shrink include orgrow exclude, add @ts-ignore, @ts-expect-error or `as any`.If an error needs one of those, stop and list it for me.Step 2: 두 컴파일러가 같은 트리를 채점하게 하라
에이전트가 결과를 보고하면, worktree에서 두 컴파일러를 모두 실행해 오류 목록을 비교합니다:
errs() { grep -E 'error TS[0-9]+' "$1" | sort; }npx tsc6 --noEmit --pretty false --stableTypeOrdering > /tmp/t6.txtnpx tsc --noEmit --pretty false > /tmp/t7.txtdiff <(errs /tmp/t6.txt) <(errs /tmp/t7.txt)wc -l /tmp/t6.txt /tmp/t7.txt--stableTypeOrdering은 6.0에서 추가된 플래그로, 타입 정렬이 7.0과 맞도록 해 줍니다. 6.0 게시글에 따르면, 이는 "두 코드베이스 사이의 차이 수를 줄여 줍니다." 다만 6.0을 눈에 띄게 느리게 만들 수 있는데( 같은 게시글에 따르면 최대 25%까지), 리뷰할 때 한 번만 실행하는 확인 작업이라면 문제 없습니다. 정렬을 해 두면 비교가 각 컴파일러의 출력 순서에 의존하지 않습니다.
원하는 것은 빈 파일 두 개입니다. 그렇지 않을 때 출력이 말해 주는 것:
tsc6에서만 발생하는 오류. 가장 가능성 높은 경우는 에이전트가 7.0으로만 확인하고 멈춘 것입니다. 당신의 편집기와 typescript-eslint는 여전히 6.0에서 실행되므로, 이것들은 실제 문제입니다.tsc에서만 발생하는 오류. 7.0이 다르게 동작하는 지점을 찾은 것입니다. 코드를 탓하기 전에 포트의 CHANGES.md를 확인하세요. 예를 들어, 충돌하는 선언은 이제 기여한 모든 위치에서 오류가 난다고 적혀 있으므로, 예전에는--skipLibCheck가 가려 주던 일부가 이제는 자신의.ts파일에 나타날 수 있습니다.- 두 쪽 모두 같은 오류가 나오는데 에이전트가 “완료”라고 말한 경우. 에이전트의 요약이 틀렸고, 두 오류 파일이 그것을 보여 줍니다.
Step 3: JavaScript도 비교하라
깨끗한 타입 체크가 dist/에 무엇이 들어가는지까지 보장해 주지는 않습니다. target: es5를 제거하거나 module을 바꾸면 배포되는 코드가 달라집니다. 그것이 바로 원하는 변경일 수도 있지만, 확인은 해야 합니다.
같은 프로젝트를 세 가지 방식으로 출력한 뒤 폴더를 diff 하세요:
# in your main checkout (still on 6.0, so tsc is 6.0 here)npx tsc --outDir /tmp/emit-main# in ../app-ts7, the same tree through both compilersnpx tsc6 --outDir /tmp/emit-6npx tsc --outDir /tmp/emit-7diff -r /tmp/emit-main /tmp/emit-6 | head -80diff -r /tmp/emit-6 /tmp/emit-7tsconfig에 번들러가 빌드를 맡기기 때문에 noEmit이 설정돼 있다면, 각 줄에 --noEmit false를 추가하세요.
첫 번째 diff는 에이전트의 수정이 출력물에 어떤 영향을 주었는지 보여 줍니다. 즉, 소스 수정과 설정 변경의 결과입니다. 모든 hunk는 에이전트 diff의 어떤 한 줄로 거슬러 올라가야 합니다. 변경된 파일이 그렇게 연결되지 않는다면, 머지하기 전에 에이전트에게 이유를 물어보세요. 예외가 하나 예상되는데, 에이전트가 명시적인 rootDir를 설정했다면 출력 폴더들이 더 이상 정확히 일치하지 않으므로, 두 루트 대신 대응되는 하위 폴더(종종 /tmp/emit-main/src)와 /tmp/emit-6를 비교해야 합니다.
두 번째 diff는 동일한 입력에서 컴파일러만 바뀐 효과를 분리합니다. 이것이 비어 있을 것이라고 기대하지는 마세요. 릴리스 게시글은 타입 체크 결과가 일치한다고 약속하지만, 바이트 단위로 동일한 JavaScript까지는 어느 쪽도 보장하지 않습니다. 또한 CHANGES.md에는 .js 입력에 대한 선언 출력이 다시 작성되었고, "Strada의 출력과 정확히 일치시키는 것은 목표가 아니다"라고 적혀 있습니다(여기서 Strada는 CHANGES.md가 6.x 컴파일러를 부르는 이름입니다). 읽어 보고, 어디까지 감수할 수 있을지 판단하세요.
Step 4: 손쉬운 수정부터 grep으로 찾아라
마지막 확인은 가장 거칩니다. 양쪽 브랜치에서 억제(suppression) 수를 세고, 에이전트가 건드린 모든 tsconfig 줄을 다시 읽으세요:
for r in main ts7-upgrade; do n=$(git grep -E '@ts-(ignore|expect-error)|as any' "$r" \ -- '*.ts' '*.tsx' | wc -l) echo "$r $n"donegit diff main...ts7-upgrade -- '*tsconfig*.json'두 번째 숫자가 첫 번째 숫자보다 크다면, git diff main...ts7-upgrade로 새로 생긴 것들을 찾아서 각각 왜 필요한지 물어보세요. tsconfig diff에서는 다음 줄들이 이유를 가져야 합니다:
strict,noImplicitAny또는strictNullChecks를false로 설정한 경우.- 새
"skipLibCheck": true. - 어떤 형태의
ignoreDeprecations든 해당됩니다. TypeScript 7은 그것이 숨기는 옵션을 지원하지 않으므로, 결국 6.0의 경고만 잠재울 뿐입니다. include가 더 짧아지거나exclude가 더 길어지는 경우. 이것이 가장 조용한 방식입니다. 제외된 파일은 아예 타입 검사를 받지 않으므로, 셀 오류 개수에 들어갈 오류가 발생하지 않습니다.
tsconfig의 모든 줄이 꼼수는 아니며, 그래서 실패했다고 바로 넘기지 말고 diff를 읽어야 합니다. 명시적인 rootDir, ["node"] 같은 types 배열, baseUrl이 사라진 뒤 다시 작성된 paths, 그리고 moduleResolution이 bundler나 nodenext로 바뀐 것은 릴리스 공지 자체가 권장하는 변경 사항입니다.
Hermes가 이 흐름에서 맡는 역할
저는 Hermes IDE 를 만들고 있으니, 이 부분은 그 점을 감안해서 봐 주세요. 위의 내용은 일반적인 git과 터미널만으로도 가능합니다. Hermes는 그 단계 중 세 가지를 줄여 줍니다.
⌘N(Windows와 Linux에서는 Ctrl+Shift+N)은 1단계의 git worktree add를 대체합니다. 에이전트는 실제 터미널에서, 자신만의 hermes/ 브랜치와 자신만의 worktree 안에서, 그리고 작업 내용을 첫 프롬프트로 받은 상태로 시작합니다. 그곳에 계약서를 붙여 넣고 Claude Code 또는 Codex를 선택하세요. 브랜치와 worktree는 일반 git이므로, 2단계부터 4단계까지의 git grep과 git diff main...는 그대로 사용할 수 있습니다.

Review Desk(⌘G)에서는 초반부터 바로 단축점이 드러납니다. 업그레이드는 긴 세션입니다. 에이전트가 설정을 수정하고, 컴파일러를 실행하고, 파일 묶음을 고치고, 다시 실행합니다. Hermes는 에이전트의 모든 턴을 저장하며, Review Desk는 변경 사항을 턴별 또는 파일별로 보여 주고 위험 플래그도 표시합니다. 턴 단위로 보면 3번째 턴에서 이루어진 tsconfig 수정은 주변의 소스 파일 40개가 섞인 큰 diff 안에 묻히지 않고 따로 드러납니다. 해당 턴만 diff 하거나 복원할 수 있고, 되돌리기도 가능하며, 줄 코멘트는 그 줄을 작성한 에이전트에게 다시 전달됩니다.

2단계부터 4단계까지의 검사 결과가 깨끗하면 Land 버튼이 커밋을 만들고, pull request를 열거나 작업이 시작된 브랜치에 로컬로 병합하며, 이 동작은 되돌릴 수 있습니다. Hermes는 작업 완료 시점을 정하는 기준도 여러분이 직접 정할 수 있게 합니다. worktree recipe 문서에는 저장소의 .hermes/worktree.toml에 done_when 목록을 두는 예시가 나와 있으며, 2단계의 npx tsc6 --noEmit과 npx tsc --noEmit이 그 목록의 가장 분명한 항목입니다.
7.1이 나오면 심판은 물러난다
이 설정에는 유통기한이 있습니다. 7.1이 API를 출시하고 이를 사용하는 도구들이 그쪽으로 옮겨 가면, 대부분의 프로젝트는 @typescript/typescript6를 제거할 수 있고, 그러면 이런 종류의 검토를 싸게 만들어 주던 두 번째 컴파일러도 함께 사라집니다. 지금은 두 구현체가 같은 결과를 내도록 의도되어 있고, 둘 다 설치되어 있으며, 둘 다 npx 한 번이면 실행됩니다.
그러니 지금 에이전트에게 지루한 작업을 맡기세요. baseUrl 제거, paths 재작성, 수백 개 파일을 가로지르는 모듈 해석 오류 추적 같은 일입니다. tsc6가 아직 devDependencies에 있을 때 2단계부터 4단계까지의 검사를 실행하고, 그 뒤에 에이전트의 요약을 읽으세요. 7.1이 도입되면, 여러분은 한 개의 컴파일러로 에이전트를 평가하게 될 것입니다.
더 깊이 들어가고 싶다면
Hermes IDE는 무료로 내려받을 수 있고, BSL 1.1 라이선스의 소스 공개 형태로 제공되며, macOS, Windows, Linux에서 실행됩니다. Nous Research, Anthropic, OpenAI 또는 어떤 에이전트 공급사와도 제휴되어 있지 않습니다. 여기에서 다운로드할 수 있으며, 소스는 GitHub에 있습니다.
이 업그레이드의 대부분은 tsconfig와 타입 검사기에서 이루어지며, The TypeScript Type System과 TypeScript in Production은 The TypeScript Library 에서 이를 다룹니다. 위에서 제거된 옵션들이 한 번도 선택한 적 없는 설정 목록처럼 보인다면, 첫 두 권부터 시작하세요. 회사의 빌드와 tsconfig를 직접 관리하고 있다면, 마지막 책은 여러분의 것입니다.
- TypeScript Essentials — 타입, 좁히기, 모듈, 비동기, 일상적으로 쓰는 도구들
- The TypeScript Type System — 제네릭, 매핑/조건부 타입, infer, 템플릿 리터럴, 브랜디드 타입
- Kotlin and Java to TypeScript — TypeScript로 옮겨가는 JVM 개발자
- PHP to TypeScript — TypeScript로 옮겨가는 PHP 8+ 개발자
- TypeScript in Production — tsconfig, 빌드 도구, 모노레포, 라이브러리 작성, 이중 ESM/CJS, JSR
Kotlin, Java 또는 PHP를 사용해 왔다면, 자신의 언어에 맞는 브리지 북이 앞의 두 권을 대신할 수 있습니다.
다섯 권 모두 전자책, 페이퍼백, 하드커버로 제공됩니다.

출처
- 원문: https://medium.com/@anhaia.gabriel/hand-the-typescript-7-upgrade-to-a-coding-agent-then-check-it-with-tsc6-e3d17c3c7f8f?source=rss------claude_code-5 (2026-10-18 · Gabriel Anhaia)
자료 표지 보기
