TypeScript 6.0 RCやNext.js 16に上げたいけど、本番を壊したくない。そんな悩みを持つ人に向けて書いています。特に「移行はしたいけど、業務が止まるのは怖い」というチームほど、順番と検知設計で結果が変わります。この記事では、TypeScript 6.0 RC移行でつまずきやすい点、.d.ts差分をCIで自動検知する流れ、Next.js 16の型回帰テストを分離する実践手順まで、今日から使える粒度でまとめます。僕は福祉事業のIT全般を担当しながらAI×SaaS開発にも入っているので、実案件で使っている「壊さない移行フロー」をそのまま共有します。
こんな方におすすめ
- TypeScript 6.0 RCへ上げたいが、設定変更の影響が読めない方
- ライブラリ配布があり、.d.tsの破壊的変更を見逃したくない方
- Next.js 16移行で型エラーと設定回帰が混ざって困っている方
- CIで「壊れたら止まる」運用を作りたい方
この記事でわかること
- TS 6.0 RCで優先確認する破壊ポイントの洗い出し手順
--stableTypeOrderingを使った.d.ts差分の実務運用- TypeCheck・DeclarationDiff・PackageTypeHealthの3段CI設計
next typegenを軸にしたNext.js 16型回帰テストの自動化
公開前確認(2026年5月時点):TypeScript 6移行ではd.ts差分をCIで保存し、Next.jsの型生成、moduleResolution、skipLibCheckの扱いを分けて確認すると回帰を見つけやすくなります。
TypeScript 6.0 RC移行で先に潰す破壊ポイント
TypeScript 6.0 RC(2026-03-06公開)は、TS7への橋渡しとして位置づけられています。RC時点で機能はほぼ揃っていて、ここからは重大バグ修正が中心です。つまり「今触っておくと、7.0で慌てにくい」タイミングです。
イメージとしては、引っ越し当日に荷物を開けるんじゃなくて、前日に配線だけ先に確認しておく感じです。移行で痛いのは実装より設定です。僕が最初にチェックしているのは次の5点です。
baseUrlの非推奨化 — 既存の暗黙解決が崩れるのでpathsへ寄せますmoduleResolution: classic削除 — 古い解決戦略を残していると即エラーになりますoutFile削除 — 旧ビルド資産の見直しが必要ですmodule旧値の廃止 — tsconfigの互換設定を棚卸しします- CLI挙動変更(TS5112) —
tsconfig.jsonがある場所でtsc foo.tsを打つと失敗します
最初の30分でやる確認
- CIやnpm scriptsに
tsc ファイル名形式が残っていないか検索する - tsconfigで削除・非推奨オプションを一覧化する
- 暫定で
ignoreDeprecations: "6.0"を使う場合は撤去期限をIssue化する
移行初日は「直す」より「壊れる場所を固定化する」が正解です。ここを飛ばすと、後工程のテスト結果が全部ノイズになります。特にTS5112はCIだけ落ちる構成が起きやすいので、ローカルとCIの実行コマンドを同じに揃えるのがおすすめです。
.d.ts差分CIは並び順ノイズと契約変更を分ける
ライブラリや共有パッケージを持っていると、移行で一番困るのは「この差分、実害あるの?」問題ですよね。.d.tsは順序差分だけでも大きく見えるので、レビューコストが跳ねやすいです。ここで使えるのが--stableTypeOrderingです。TS6系と将来のTS7系で起きる並び順差分を抑えやすくなります。
ただし公式でも、型チェックがコードベース次第で最大25%遅くなる可能性が示されています。なので常用ジョブには入れず、比較専用ジョブに分離するのが実務向きです。
# 1) 通常の型チェック(速さ重視)
npx tsc --noEmit
# 2) 差分比較専用(順序ノイズ抑制)
npx tsc --emitDeclarationOnly --declaration --stableTypeOrdering
次に、API契約の差分を人間が読める形にします。API ExtractorのapiReportを有効化して、生成された*.api.mdをPR差分に出す運用です。
{
"apiReport": {
"enabled": true,
"reportFolder": "etc"
},
"dtsRollup": {
"enabled": true
}
}
- TypeScript差分 — 機械比較で検知する
- 公開API差分 — PR上でレビューして承認する
- 責任分界 — CODEOWNERSで公開API変更を必ず確認する
「並び順」と「契約」を分けるだけで、レビュー時間は体感で半分近くになります。つまり、騒がしい差分を静かにして、本当に危ない変更だけを目立たせるということです。
TypeCheck・DeclarationDiff・PackageTypeHealthの3段ゲート
ここからはCI実装です。僕は移行時に、ゲートを3段に分けています。1本の巨大ジョブにすると、失敗時に原因が混ざって復旧が遅くなるからです。分けるだけで、担当者の切り分け速度が上がります。
| ゲート | 主目的 | 主コマンド | 失敗条件 |
|---|---|---|---|
| TypeCheck | 通常の型安全性確認 | tsc --noEmit |
型エラーが1件でもある |
| DeclarationDiff | .d.ts契約差分の可視化 | tsc --emitDeclarationOnly --stableTypeOrdering + API Extractor |
未承認API差分がある |
| PackageTypeHealth | 公開パッケージの型解決健全性 | npx --yes @arethetypeswrong/cli --pack . |
型解決の警告/エラーがある |
name: type-safety
on: [pull_request]
jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- run: npm ci
- run: npm run typecheck
declaration-diff:
runs-on: ubuntu-latest
steps:
- run: npm ci
- run: npm run dts:diff
- run: npm run api:report
package-type-health:
runs-on: ubuntu-latest
steps:
- run: npm ci
- run: npx --yes @arethetypeswrong/cli --pack .
壊れない移行は「早く気づく設計」が9割です。もし「自分たちのCIにどう当てるか」で迷ったら、僕が実際に使っている観点で一緒に整理できます。必要なら移行設計の壁打ち相談に気軽にどうぞ。押し売りではなく、詰まりポイントの言語化だけでも歓迎です。
Next.js 16型回帰テストはTypeScriptジョブと分離する
Next.js 16移行ガイド(2026-03-17更新)は、型まわりの破壊変更がはっきりしています。params、searchParams、cookies、headers、draftModeの同期アクセスが消えて、非同期前提に統一されました。ここでのコツは、TypeScript移行とNext移行を同じジョブで見ないことです。
まずnpx next typegenを先に回して、PagePropsやLayoutPropsを基準に変換します。
import type { PageProps } from "next";
export default async function Page({ params }: PageProps<"/blog/[slug]">) {
const { slug } = await params;
return <article>{slug}</article>;
}
images.minimumCacheTTLが60秒から4時間(14400秒)へ変わり、imageSizesの既定配列から16も外れています。型が通っていても、配信挙動は変わるので監視対象を分離したほうが安全です。
競合事例でも、中規模サイトの移行が4時間で完了し、buildが11.3秒から4.2秒へ短縮した報告があります。つまり、準備を分けるほど移行自体は速くなります。型エラー修正と設定差分確認を同時にやると、どちらも遅くなりやすいので、テストジョブを分離して進めるのが現実的です。
セキュリティ回帰を含めた依存更新ルールとロールバック
移行の最後はセキュリティと戻し方です。Next.jsのセキュリティ更新(2025-12-11)では、16.0.x系の修正版が16.0.10まで進んでいます。CIで型だけ見ていると、古い安全でないバージョンが残る可能性があります。
僕は「最低セキュア版」を明示して、PR時に機械チェックしています。
さらにDependabotやRenovateの更新PRをそのまま通さず、このチェックを必須ゲートにすると運用が安定します。
# package.jsonのnextが16.0.10未満なら失敗させる例(擬似)
CURRENT=$(node -p "require('./package.json').dependencies.next")
echo "$CURRENT" | grep -Eq '^16\.(0\.([1-9][0-9]|10)|[1-9][0-9]\.)' || exit 1
- Canary環境 — TS RC + Next 16を先に適用し、型・設定・E2Eを確認します
- 段階リリース — 10%→50%→100%の順で公開し、指標を監視します
- 即時ロールバック条件 — エラー率、主要導線CVR、API失敗率の閾値を事前に決めます
- 復旧手順の固定化 — 元バージョンへ戻すPRテンプレートを準備します
「戻し方まで先に決める」と、移行の心理的コストが一気に下がります。運用設計まで含めて相談したい場合は、僕のXのDM窓口を使ってもらえたら助かります。現場前提で短く整理します。
この移行設計を後回しにした先で起きやすいこと
TypeScriptとNext.jsの大型更新を「時間ができたらやる」にすると、後からの修正コストが跳ねます。特に複数人開発では、知らないうちに古い前提が混ざって、気づいた時には手戻りが大きくなります。
- .d.tsの契約変化を見逃す — リリース後に利用側だけ壊れる可能性があります
- 型回帰と設定回帰が混ざる — 原因切り分けが遅れて、復旧が長引きます
- セキュア版未満で止まる — 問題を知らないままだと、脆弱性を抱えたまま運用する可能性があります
先に仕組みを作るだけで、アップデートは「怖いイベント」から「定例作業」に変えられます。
この記事を書いている理由
僕がこのテーマを書いているのは、実際に「壊さず更新する」難しさを何度も体験してきたからです。福祉事業のIT全般を担当しながら、別案件ではAI×SaaS開発も並行していて、React/Next.js/TypeScriptを同時に運用しています。環境もNode.js + TypeScriptのモノレポ中心なので、.d.ts差分の扱いを間違えると影響範囲が一気に広がります。
過去に結婚式Web招待状サービスを作った時も、リリース後の体験を壊さない改善を続けて、90日以上のログイン継続率を維持しました。僕自身が「更新の速さより、体験を守る設計が先」と痛感したからこそ、この手順を共有したいんです。
次のアクション
運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。
今日からできるアクション
- Step1 — d.ts差分ジョブを追加する
- Step2 —
apiReportをPR差分に出す - Step3 —
next typegenをCIに組み込む