TypeScript 7 移行コストはlintで変わる — 3プロジェクトで分かれた導入と見送り
TypeScript 7 移行で、アプリコードを1行も触らず終わった1件と、TypeScript 6 との併用構成が必要になった2件。何が両者を分けたのか、CI の実測値と、npm ci の失敗を含む4つの運用コストから、導入する条件と待つ条件を整理します。「TypeScript 7 は10倍速い」という数字を見て、社内のリポジトリを一斉に上げる計画を立てていないでしょうか。
TypeScript 7.0 に上げられるかを最初に切り分けるのは、「Compiler API を import するツールに依存しているか」です。 実務でここに当たるのは lint であることが多く、私たちの3プロジェクトも lint に何を使っていたかで結果が分かれました(ts-jest や ts-node のようなテスト・実行系も同じ分類に入ります)。該当すれば、TypeScript 6 との併用構成を組むか 7.1 を待つかの判断になります。該当しなければ移行のハードルは大きく下がりますが、その場合でも typescript を peer dependency に持つライブラリの監査と、tsconfig.json の非互換の確認は必要です。TECH PLAY では3つのプロジェクトで検証し、1つに導入して2つを見送りました。導入した1つは、設定ファイル4つの変更だけで済み、アプリケーションコードは1行も触っていません。
急いでいる方のために、結論だけ先に3行で示します。
- 該当するツールがなければ移行のハードルは下がりますが、peer dependency と tsconfig.json の確認は必要です
- 該当するなら、7.1 とツール側の対応を待つ方が安く済む可能性が高いです
- どちらの場合でも、
npm ls typescriptによる事前監査は必要です。 怠るとnpm ciが落ち、コンテナのビルドを経由してデプロイが止まることがあります
本記事は判断に必要な範囲に絞ります。移行手順そのものと tsconfig.json の破壊的変更は、前回の記事(TypeScript 7.0 RCの10倍速は本当か?)で扱っています。検証はすべて npm で行っており、pnpm と yarn、およびモノレポ構成は未検証です。
何が変わって、何が変わっていないか
TypeScript 7.0 は2026年7月8日に正式リリースされました(公式ブログ、typescript@7.0.2)。コンパイラが Go で再実装され、型システムと構文は TypeScript 6.0 と互換です。
移行判断に効いてくるのは、速度ではなく次の一文です。
While TypeScript 7.0 is here, it does not ship with an API. We expect TypeScript 7.1 to ship with a new (and different) API, but until then we have made it a priority to ensure TypeScript can be run side-by-side with TypeScript 6.0 for utilities that still need some programmatic access to the compiler (such as typescript-eslint).
つまり 7.0 には、従来の Compiler API と互換性のある安定したプログラマティック API がありません。ts.createProgram() のような Node.js 向け API を使っていたツールは、そのままでは動きません。公式は 7.1 で新しい API を提供するとし、リリースは "new featureful versions published every 3-4 months" のケイデンスに戻ると表明しています。7.0 が7月8日なので 2026年10〜11月ごろが目安ですが、公式が日付を明言しているわけではありません。
最初の切り分け — Compiler API を import しているか
ツールが TypeScript とどう関わっているかで、影響は4つに分かれます。分類してみると、プロジェクトに TypeScript 7 を入れたときに直接壊れるのは4つ目だけです。
| 依存形態 | 代表例 | プロジェクトに素の TS 7 を入れたとき |
|---|---|---|
tsc を外部プロセスとして起動 | CI の型チェック、vitest typecheck | 動く。高速化の恩恵あり |
| 独自パーサーを持つ | Biome、esbuild | 動く。TS のバージョンに非依存 |
| TypeScript を同梱している | ts-morph | 動く。ただし高速化はなし |
Compiler API を import する | typescript-eslint、ts-jest | 動かない |
表だけでは判断しづらいので、主要ツールについて1行ずつ状況を書いておきます。
- typescript-eslint は素の TypeScript 7 では動きません。 最新の 8.67.0(2026年8月10日公開)でも peer dependency は
typescript: ">=4.8.4 <6.1.0"のままで、7.x をインストールすると解決に失敗します(対応 Issue #10940)。 - ts-jest は素の TypeScript 7 では動きませんが、併用構成なら動きます。 29.4.12(2026年7月22日公開)で TypeScript 7 を検出し、エラーメッセージで対処法まで案内するようになりました。
- ts-morph は TypeScript 7 を入れても影響を受けません。
@ts-morph/commonが TypeScript 6.0.2 を同梱しており、インストール済みのtypescriptパッケージを参照しないためです。ts-morph 28.0.0(@ts-morph/common0.29.0)で確認し、require('ts-morph').ts.versionは6.0.2を返しました。ただし解析に使われるのは同梱の TypeScript 6 なので、CI の型チェックと診断結果が食い違う可能性はあります。この点は「TypeScript の AST を扱うツールだから壊れる」と誤って紹介されていることがあるため、手元で確認してみてください。 - Biome と vitest は影響を受けません。 Biome は独自パーサーで解析し、vitest はテストの変換を esbuild が担当します。
vitest typecheckを使っている場合はtscを外部起動するため、こちらは TypeScript 7 の高速化がそのまま効きます。
3つ目の「同梱している」を独立させているのは、ここを見落とすと判定を誤るからです。ts-morph は TypeScript の AST を扱うライブラリなので直感的には影響を受けそうですが、実際には自前で TypeScript を抱えているため無傷です。「TypeScript の AST を扱うか」ではなく「インストール済みの typescript パッケージを参照するか」で分類してください。
本記事で実際に検証したのは上記5ツールです。次のツールは未検証ですが、Compiler API を利用する構成が一般的なため、4つ目に該当する可能性があります。 使っている場合は、それぞれの peer dependency の範囲と API 利用の有無を確認してください。
- ts-node、ts-loader、fork-ts-checker-webpack-plugin
- vue-tsc、svelte-check、Angular のビルドツール群
ただし状況は動いています。たとえば svelte-check は 4.7.4 で「npm alias 経由の TypeScript 7 Stable への対応」を入れ、--tsgo-experimental-api という実験的な経路も持っています(peer の範囲は 4.7.6 時点でも ^5.0.0 || ^6.0.0 のままです)。この分類は出発点として使い、実際に使っているツールについては最新の CHANGELOG を確認してください。
Next.js は4つ目に入ります
読者の多いフレームワークなので、Next.js だけソースコードを確認しました(next@16.0.8)。next build の型チェックは Compiler API を直接呼んでいます。
// next/dist/lib/typescript/runTypeCheck.js
program = typescript.createProgram(effectiveConfiguration.fileNames, options);
const allDiagnostics = typescript.getPreEmitDiagnostics(program)...
typescript は Next.js に同梱されておらず、利用者の node_modules から解決して読み込まれます。つまり分類上は4つ目です。
ただし実際に TypeScript 7 を入れると、この API 呼び出しまで到達しません。手前の依存チェックで止まります。Next.js は typescript パッケージの有無を、typescript/lib/typescript.js というファイルが実在するかで判定しているためです。
TypeScript 7.0.2 の lib/ 配下
getExePath.js / tsc.js / version.cjs / version.d.cts
→ typescript.js が存在しない
結果として、TypeScript 7 が入っているのに「TypeScript がインストールされていない」と判定されます。エラーメッセージから原因にたどり着きにくい種類の失敗です。
next.config の typescript.ignoreBuildErrors は型チェック自体をスキップしますが(型定義のコメントは「Do not run TypeScript during production builds (next build).」)、この依存チェックは別に走るため、これだけでは回避できません。
なおこれはソースコードを読んで確認した結果で、TypeScript 7 の環境で実際に next build を実行したわけではありません。Next.js を使っていて TypeScript 7 に興味がある場合は、まず検証ブランチで試すことをおすすめします。
なお、この分類で判定できるのは「TypeScript 7 のコンパイラに差し替えられるか」までです。実際に移行するかどうかは、後述する peer dependency の状況、CI で得られる効果、併用構成の運用コストを合わせて決めることになります。
「動かない」の中身を実機で確かめる
ここは切り分けに詰まったときに読む節です。判断だけを急ぐ場合は次のセクションへ進んでください。
「Compiler API に依存するツールはクラッシュする」とだけ書かれている記事が多いのですが、実際の壊れ方は参照の仕方によって変わります。TypeScript 7.0.2 を入れた環境で確認した結果が以下です。
# typescript@7.0.2 の環境で実行
require('typescript') → 成功(キーは version と versionMajorMinor の2つだけ)
ts.createProgram() → TypeError: ts.createProgram is not a function
require('typescript/lib/typescript') → ERR_PACKAGE_PATH_NOT_EXPORTED
require('typescript/lib/tsserverlibrary') → ERR_PACKAGE_PATH_NOT_EXPORTED
require('typescript/unstable/ast') → ERR_REQUIRE_ESM
主エントリの import ts from "typescript" は成功します。 失敗するのは API を呼んだ瞬間です。一方、typescript/lib/tsserverlibrary のような深いパスを直接読むツールは、モジュール解決の段階で落ちます。エラーが全く違うので、原因の切り分けに使えます。
理由はパッケージの exports にあります。
// typescript@7.0.2 の package.json(抜粋)
{
"exports": {
".": "./lib/version.cjs",
"./unstable/sync": "./dist/api/sync/api.js",
"./unstable/ast": "./dist/ast/index.js"
}
}
主エントリはバージョン情報だけを返すスタブに差し替えられ、lib/typescript や lib/tsserverlibrary は公開されていません。./unstable/* の新しい API は既に存在しますが、名前のとおり安定版ではなく、ESM でのみ読み込めます。
上げた側 — 変更は4ファイル、アプリケーションコード0行
ここから3プロジェクトの実例です。分かれ目は lint に何を使っていたかでした。
3つのうち、実際に本番投入したのは参加者向けの Web アプリです。lint に Biome を使っており、型チェックは CI で tsc --noEmit を外部起動しているだけでした。つまり先ほどの表の1つ目と2つ目にしか該当しません。
必要だった変更は、パッケージロックファイルを除くと4ファイル、追加15行・削除2行でした。アプリケーションコードの変更は0行です。
なお、これは変更量であって移行コストではありません。実際にかかった時間は計測していないため人日は出せませんが、工程は「依存の監査 → tsconfig の修正 → 型宣言の追加 → CI での確認 → ビルド成果物の比較」の5つでした。見積もる際の参考にしてください。
// package.json
- "typescript": "^5.0.2",
+ "typescript": "^7.0.2",
+ "@types/mdx": "^2.0.13",
// tsconfig.json
- "baseUrl": ".",
@types/mdx を追加したのは、MDX の型定義を間接的な依存に頼っていたためです。baseUrl は TypeScript 7 で廃止されているので削除しました。なお package.json の指定は ^5.0.2 でしたが、ロックファイル上の実体は 5.9.2 です。次に示す CI の実測は、この 5.9.2 との比較になります。
アンビエント宣言の短縮形に注意する
TypeScript 7 では noUncheckedSideEffectImports がデフォルトで有効になるため、CSS や MDX のような副作用インポートに型宣言が必要になります。ここで1箇所つまずきました。
// TypeScript 7.0.2
// NG: MDX の型が any になり、型チェックが素通りする
declare module "*.mdx";
// OK: 同梱の型定義を明示的に参照する
declare module "*.mdx" {
import type { Element, MDXProps } from "mdx/types";
export default function MDXContent(props: MDXProps): Element;
}
短縮形でもエラーは消えます。ただしその型は any になり、@types/mdx の型定義を上書きしてしまいます。エラーが消えたことで対処済みだと判断しやすい箇所なので、宣言を書いたあとに型が効いているかを確認してください。
CI の実測値
本番の GitHub Actions で、移行前後を4回ずつ計測しました。
| 工程 | TypeScript 5.9.2(4回) | TypeScript 7.0.2(4回) |
|---|---|---|
| 型チェック + lint | 13〜15秒 | 3〜7秒 |
| 依存インストール | 10〜12秒 | 8〜14秒 |
| ユニットテスト | 44〜48秒 | 45〜98秒 |
| Storybook のテスト | 66〜70秒 | 67〜133秒 |
数字の読み方に注意が要ります。TypeScript 7 側の4回のうち2回は、全工程が一様に遅くなっています。 ユニットテストが最大98秒と基準の2倍を超えており、これは TypeScript ではなくランナー側の性能変動です。型チェック以外の工程では、この変動がバージョン差を完全に覆い隠しています。
裏を返すと、型チェックだけは変動を突き抜けています。TypeScript 7 の4回のなかでも3秒から7秒までばらつきましたが、最も遅かった7秒でも移行前の最速13秒を下回りました。この工程は tsc --noEmit と biome lint をまとめて実行しているため tsc 単体の短縮率は分離できていませんが、短縮そのものは変動に埋もれない大きさだと言えます。
依存インストールについては、TypeScript 7 が Go 製のネイティブバイナリをプラットフォーム別のパッケージとして配布しており、今回のロックファイルには20プラットフォーム分が記録されました。実際に展開されるのは実行環境に一致する1つだけです。解決対象は増えますが、上記のとおり変動幅の方が大きく、今回の時間差の原因がこれであるとは確認できませんでした。
そして重要なのは、ジョブ全体の時間が短縮されていないことです。4回の総時間は3分5秒から5分48秒まで散らばり、最も遅い回はランナーの変動でむしろ大幅に伸びました。型チェックで得られる10秒弱は、テストとビルドが大半を占める構成では全体への寄与がわずかなうえ、ランナーの変動幅よりも小さいのです。「CI が劇的に速くなる」という期待で導入すると、投資対効果の説明に困ることになります。
では、なぜこのプロジェクトを上げたのか。CI の短縮そのものが目的ではありませんでした。変更量がごく小さく、アプリケーションコードに触れずに済んだことと、7.1 以降に他のプロジェクトを動かすときの前例を、リスクの低いところで先に作っておきたかったことが理由です。型チェックの短縮は、開発者がローカルで tsc を回す頻度を考えれば体感には効きますが、稟議に使えるほどの数字ではありません。
テストの結果は完全に一致しました。ユニットテスト77ファイル1,059件、Storybook のインタラクションテスト133スイート1,112件が、いずれも移行前と同じ件数で通過しています。
noEmit 構成では、TypeScript は成果物を直接生成しない
型チェックのバージョンを上げると、生成される JavaScript も変わるのではないかと不安になるかもしれません。このプロジェクトの tsconfig.json は noEmit: true を指定しており、tsc は JavaScript を1バイトも出力しません。変換を担当しているのは esbuild と rollup です。
実際に移行前後のビルド成果物を比較した結果が以下です。
| 比較項目 | 結果 |
|---|---|
| 生成チャンク | 406個中405個がバイト単位で完全一致 |
| 差分のあった1個 | 44バイト差。文字列リテラル10,367件はすべて一致 |
差分のあった1個については、文字列リテラルが完全に一致していることから、minifier が変数名を割り当てる順序がずれたものと考えられます。確認した範囲では、機能的な差やテストの失敗は検出されませんでした。ただし同一バージョンでの再ビルドによる非決定性の検証までは行っていないため、この1個の差の原因を確定したわけではありません。
この結果は noEmit 構成での観測です。tsc に emit させているプロジェクトには当てはまりません。型チェック専用ツールとして使っている場合に限り、成果物への影響は考えなくてよい、と読んでください。
見送った側 — 併用構成が持ち込む4つの運用コスト
残る2つ、管理画面と主催者向け CMS は typescript-eslint を使っています。この場合、TypeScript 6 と 7 を同居させる併用構成が必要です。公式が推奨する形は以下です。
// package.json(TypeScript 7.0 公式ブログの推奨形)
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
}
設定自体は2行です。しかし実際に組んでみると、想定していなかった問題が続きました。
1. npm ci が失敗し、デプロイが止まる
最初に踏んだのはこれです。原因を typescript-eslint だと考えて調べていましたが、実際には違いました。なおこの項目だけは併用構成に固有ではなく、TypeScript 7 に移行するすべてのプロジェクトに当てはまります。
止めていたのは i18next と react-i18next の optional peer dependency でした。 これらは typescript を任意の peer として宣言しており、当時使っていたバージョンの範囲が ^5 だったため、併用構成で typescript の実体が 6.x になると解決に失敗します。
問題はこれが開発環境だけの話ではないことです。コンテナのビルド定義に npm ci が含まれている場合、イメージのビルドが失敗してデプロイが止まります。ローカルで型チェックが通っていても、リリース時に初めて気づく類の問題です。
私たちは検証段階で気づいたため本番影響はありませんでしたが、npm install は通って npm ci だけが落ちるという挙動だったので、ローカルで作業している限り気づけませんでした。移行作業では早い段階で npm ci を試してください。
このケース自体は既に解消しています。i18next は 26.3.6(2026年7月9日公開)、react-i18next は 17.0.9 で peer の範囲が ^5 || ^6 || ^7 に広がりました。私たちが踏んだのは、これらを古いバージョンで固定していたためです。
ただし教訓は2つ残ります。
1つ目は、原因が疑っているツールとは限らないことです。typescript を optional peer として宣言しているライブラリは想像より多く、しかも optional なので普段は存在を意識しません。移行前に npm ls typescript で参照元を洗い出しておくと、この手戻りを避けられます。
2つ目は、これが併用構成に固有の問題ではないことです。peer の範囲が ^5 のままなら、併用構成を組まずに素の TypeScript 7 を入れても同じように解決に失敗します。つまり前掲の4分類でどこに該当するかとは無関係に、peer dependency の監査は全プロジェクトで必要です。私たちが導入した Web アプリで露見しなかったのは、単にこれらのライブラリを使っていなかったからでした。
2. .npmrc の legacy-peer-deps は回避策にならない
peer dependency の衝突を黙らせる定番の手段として .npmrc に legacy-peer-deps=true を書く方法があります。これは使えませんでした。
このフラグは peer dependency の自動インストールも止めるため、ロックファイルから134パッケージが消えます。その中には stylelint のように CI で実際に使っているツールも含まれていました。エラーは出ないまま、必要なパッケージが入らなくなります。
3. alias 名を変えると tsc が別のバージョンを指す
前掲の推奨形なら問題は起きません。TypeScript 7 側が tsc、TypeScript 6 側が tsc6 を提供するため、コマンド名が衝突しないからです。
ただしこの形になったのは、一度問題が報告されたあとです。公式ブログは当初、TypeScript 7 側の alias 名を typescript-7 としていました。ところが @typescript/typescript6 は内部で @typescript/old(実体は TypeScript 6)に依存しており、こちらも tsc を提供します。つまり tsc を提供するパッケージが2つある状態でした。
このとき npm は依存関係の深さではなく、パッケージ名の辞書順で勝者を決めます。@typescript/old は typescript-7 より前に並ぶため、npx tsc が TypeScript 6 を指してしまうという報告が上がりました(typescript-go #4567)。TypeScript チームの Ryan Cavanaugh も「npm は依存の深さではなく辞書順で bin の勝者を決める」と回答しています。
現在の @typescript/native という名前は、@typescript/old より辞書順で前に来ます。名前で勝たせているわけです。
したがって、alias 名を自分で変えると同じ罠にはまります。負けても警告は一切出ず、npx tsc --noEmit が古いバージョンで実行され、新しいコンパイラで検査したつもりが実際にはされていない状態になります。構成を変えたら npx tsc --version で確認してください。
4. エディタは workspace のバージョンを選べない
併用構成では従来の tsserver.js がインストールされないため、VS Code の「Use Workspace Version」で TypeScript 7 を選ぶことができません。
ただしこれは「エディタで TypeScript 7 が使えない」という意味ではありません。公式が VS Code 向けに TypeScript 7 拡張(ID は TypeScriptTeam.native-preview)を提供しており、インストールすれば TypeScript 7 が既定の体験になります。コマンドパレットの「Disable TypeScript 7 Language Server」でいつでも切り戻せます。Visual Studio は、最新版であればワークスペースを見て自動的に有効化します。
問題は、エディタ側のバージョンが package.json から切り離される点です。拡張を入れていないメンバーの手元では TypeScript 6、CI では TypeScript 7 という状態になり、診断結果の差異が疑われたときに確認すべき箇所が1つ増えます。チーム全体で拡張の導入状況を揃えておく必要があります。
見送りの判断
これらを踏まえた判断は次のとおりです。得られるものは型チェック工程の短縮のみで、支払うのはデプロイ停止のリスクと、上記4つを理解しているメンバーを維持し続けるコストです。 現時点では待つ方が安いと結論しました。
ただしこの判断は待機期間の見込みに依存しています。7.1 のリリースが遅れたり、ツール側の対応にさらに時間がかかったりすれば、併用構成を組んで先に恩恵を得る方が合理的になる可能性はあります。私たちは 7.1 の動向が見えた時点で判断を見直す予定です。
なお主催者向け CMS については、そもそも CI で型チェックを実行していないため、移行しても短縮される工程が存在しませんでした。
3プロジェクトを横に並べる
ここまでの判断を一覧にします。
型チェック時間はローカルで計測した中央値で、.tsbuildinfo を削除して5回ずつ実行した値です。3プロジェクトを比較できるよう、移行前の側は TypeScript 6.0.3 に揃えて計測しています(Web アプリの実際の移行前バージョンは 5.9.2 でした)。先ほどの CI の数値は biome lint を含む工程全体なので、こちらとは別の計測です。
| プロジェクト | lint | 型チェック(6.0.3 → 7.0.2) | 判断 |
|---|---|---|---|
| 参加者向け Web アプリ | Biome(Compiler API 非依存) | 18.39秒 → 2.39秒 | 導入 |
| 管理画面 | typescript-eslint(依存) | 9.68秒 → 1.83秒 | 見送り |
| 主催者向け CMS | typescript-eslint(依存) | 4.48秒 → 0.93秒 | 見送り |
結果を分けたのは lint でした。 Biome を使っていた1件は素の TypeScript 7 に上げられ、typescript-eslint を使っていた2件は併用構成が要るため見送りになっています。見送った2つは「ツールが対応するまで待つ」という同じ理由ですが、CMS はもともと CI で型チェックを実行していないため、仮に移行しても CI 上の短縮はゼロでした。
なお、これは「lint さえ通れば必ず導入できる」という意味ではありません。判断軸はあくまで Compiler API への依存で、lint 以外にも ts-jest や ts-node が同じ位置にあります。今回の3件では、たまたまその依存の有無が lint の選択として現れた、というのが正確なところです。
規模と高速化の倍率を並べると、もう1つ分かることがあります。
| プロジェクト | 自前の .ts/.tsx | tsc プログラム全体 | 倍率 |
|---|---|---|---|
| 参加者向け Web アプリ | 929 | 2,144 | 7.7x |
| 管理画面 | 394 | 2,181 | 5.3x |
| 主催者向け CMS | 204 | 599 | 4.8x |
今回の3件では、倍率は自前コードの量と同じ順序になりました。 一方、プログラム全体のファイル数とは対応していません。管理画面と Web アプリは .d.ts を含めたファイル数がほぼ同じ(2,181 と 2,144)なのに、倍率は 5.3x と 7.7x で開きます。
ただし3件だけの観測で、型の複雑さや依存する型定義の量といった他の要因を揃えたわけではありません。自前コードの量が倍率差の原因だと断定はできません。
それでも実務上の示唆はあります。公式が示す10倍前後の数字は大規模なコードベースでの値であり、手元のプロジェクトで同じ倍率が出るとは限りません。 期待値は自分の環境で測ってから決めてください。
第3の選択肢 — lint を乗り換える
ここまで「併用構成を組む」か「待つ」の2択で書いてきましたが、分岐点が lint である以上、lint 自体を乗り換えるという選択肢もあります。実際、私たちが導入できた1件は、もともと Biome を使っていたから素の TypeScript 7 に上げられました。
ただしドロップイン置換ではありません。Biome にも型情報を使うルール群(Types ドメイン)はありますが、公式ドキュメントはその仕組みをこう説明しています。
This domain contains rules that perform project-level analysis. This includes our module graph for dependency resolution. When enabling rules that belong to this domain, Biome will scan the entire project, and it will enable the inference engine to resolve and flat types.
型を解決するのは TypeScript のチェッカーではなく、Biome 自身の推論エンジンです。公式もプロジェクト全体をスキャンするため lint の性能に影響が出ると明記しています。
そして重要な点として、noFloatingPromises や noMisusedPromises といった代表的なルールは、いずれも nursery(実験的)扱いです。types: "recommended" を指定しても nursery のルールは有効にならないため、明示的に有効化する必要があります。typescript-eslint の安定したルールをそのまま置き換えられる段階ではありません。
つまり typescript-eslint の型情報ルールに強く依存しているほど、乗り換えは「TypeScript 7 のために lint の検査内容を変える」判断になります。失うルールと、得られる型チェックの短縮を天秤にかける話です。
私たちはこの乗り換えを検証していません。ただ、選択肢が「併用構成/待つ」の2つしかないと思い込むと、判断を誤ります。lint を変えられる余地があるなら、それが最も筋の良い解になることもあります。
判断フローと、併用構成を撤去するとき
判断の分岐を先にまとめます。ADR や検討メモにはこの表を使ってください。
| 状況 | 判断 | 再評価の条件 |
|---|---|---|
| Compiler API 依存なし | 移行を検討する | — |
| 依存あり・CI から外せる | 外して移行を検討する | — |
| 依存あり・lint が原因で乗り換え可能 | lint の乗り換えを検討する | — |
| 依存あり・型チェックが CI の大半を占める | 併用構成を検討する | ツールの新 API 対応 |
| 依存あり・型チェックの比重が小さい | 待つ | ツールの新 API 対応 |
そのうえで、実際に確認する手順は次のとおりです。手順1と手順2は別物なので、混同しないでください。
- Compiler API を
importするツールがあるか確認する。 typescript-eslint、ts-jest が代表例です。ts-node、ts-loader、vue-tsc なども該当する可能性があります。あった場合は、CI で外せるかを検討し、外せなければ併用構成を組むか 7.1 を待つかの判断になります。 npm ls typescriptで、typescriptを peer dependency に持つライブラリを洗い出す。 こちらは手順1とは別の集合で、API を使っていなくても該当します。範囲が古いだけならライブラリのバージョンアップで解決するため、7.1 を待つ理由にはなりません。- 公式の非互換一覧に対して tsconfig.json を検査する。
baseUrlのほかにtarget: es5、古いmoduleResolution、rootDirとtypesのデフォルト変更などがあります。必要な変更は構成ごとに異なります。 - 現在の型チェック時間と、それが CI 全体に占める割合を測る。 ここが小さいなら、急いで移行する便益もそれだけ小さくなります。
- 検証ブランチで型チェック・ビルド・テスト・エディタ動作を確認する。 あわせて
npx tsc --versionで、実際に 7.x が使われているかを確認してください。
併用構成を組んだ場合、それを撤去できるのは 7.1 がリリースされた時点ではなく、利用しているツールが新しい API への対応を終えた時点です。公式は "a new (and different) API" と表現しており、API が刷新される以上、ツール側の移植にはさらに時間がかかる可能性があります。撤去そのものは、alias を通常の依存に戻し、.npmrc の回避策を削除し、.bin のバージョンを確認する、という順で進められます。併用構成を組む場合は、撤去の時期が読めないことを前提に、設定の理由をコメントとして残しておいてください。
まとめ
TypeScript 7.0 は「全部上げるか、全部待つか」の二択ではありません。
- 最初の切り分けは Compiler API を
importするツールに依存しているか です。私たちの3件では、これは lint に何を使っているかの違いとして現れました。ここで分かれた先に、peer dependency の状況・tsconfig の非互換・CI で得られる効果という判断が続きます - 該当しないプロジェクトなら移行は現実的です。TECH PLAY の事例では4ファイル・追加15行で、アプリケーションコードの変更は0行でした。ただし必要な変更量は tsconfig.json の状態によって変わります
- 該当するプロジェクトについては、私たちは 7.1 を待つ方が総コストは低いと判断しました。ただし待機期間は 7.1 のリリース時期だけでなく、ツール側の対応時期にも左右されます
- 選択肢は「併用構成/待つ」の2つではありません。原因が lint にあるなら lint を乗り換えるという道もあります。ただし Biome の型情報ルールはまだ実験的な段階なので、失うものと得るものを比べて決めてください
まず手元の package.json を開いて、本記事の4分類のどれに当てはまるかを確認してください。あわせて npm ls typescript を実行しておくと、移行時に npm ci が落ちる事故を防げます。
移行手順の詳細、tsconfig.json の破壊的変更の一覧、速度ベンチマークについては、TypeScript 7.0 RCの10倍速は本当か?実プロジェクトで6.7〜8倍を実測、移行の落とし穴も解説で扱っています。あわせて参照してください。
参考文献
- Announcing TypeScript 7.0 - TypeScript Blog(2026年7月8日)
- Announcing TypeScript 7.0 RC - TypeScript Blog(2026年6月18日)
- Enhancement: Use TS 7 (tsgo / typescript-go) for type information - typescript-eslint
tscincorrectly points to v6 rather than v7 - typescript-go- TypeScript 7.0 RCの10倍速は本当か?実プロジェクトで6.7〜8倍を実測、移行の落とし穴も解説 - TECH PLAY(2026年6月28日)












