第07章:SemVer(X.Y.Z)をやさしく理解する🔢✨
この章でできるようになること🎯✨
- MAJOR / MINOR / PATCH を見て「何が起きそうか」を説明できる🙂📣
- 変更内容から「どの番号を上げる?」を自分で判定できる🧠✅
- TypeScriptライブラe(型も契約!)で、破壊変更をうっかり混ぜないコツが分かる🟦⚠️
- npm の ^ / ~ の意味を理解して、事故りにくい依存指定ができる📦🧯
7.1 SemVerってなに?🤝🔢
SemVer(Semantic Versioning)は、バージョン番号 X.Y.Z に「変更の意味」を入れるルールだよ✨ 利用者は番号を見るだけで、だいたいこう予測できるようになる💡
- X(MAJOR):大きめに壊れるかも…!😱
- Y(MINOR):機能増えそう!でも基本は壊さないはず😊
- Z(PATCH):バグ直し中心で安心寄り🩹✨
SemVer の仕様は「**公開API(Public API)**がどう変わったか」で判断するのがポイントだよ🚪✨ (Semantic Versioning)
7.2 まず覚える3ルール📏🌈
![]()
SemVerの超基本はこれだけでOK👇✨(1.0.0以降の話ね)
-
PATCH(x.y.Z):公開APIはそのまま、後方互換なバグ修正🩹
-
MINOR(x.Y.0):公開APIに後方互換な機能追加✨
- さらに大事!非推奨(Deprecated)を付けたら MINOR にするのがルール🛟
-
MAJOR(X.0.0):公開APIに**後方互換のない変更(破壊変更)**😱💥
この「非推奨は MINOR」って意外と忘れがちだから要注意だよ〜!🚧✨ (Semantic Versioning)
7.3 “公開API(Public Surface)”が分かると、判定が激ラク🎭🚪
SemVerは「利用者に約束してる部分=公開API」が変わったかで決めるよ📌 たとえば TypeScript のライブラリなら、だいたいこのへんが公開APIになりがち👇
- export してる 関数 / クラス / 型 / 定数 🟦📤
- 公開してる JSONの形(DTO)🧾
- 公開APIの 振る舞い(意味) 🧠
- “動く”だけじゃなくて、型としての約束も含まれることが多い✨
「公開APIが変わったか?」の問いに答えられると、SemVerが一気に簡単になるよ🙂🎀 (Semantic Versioning)
7.4 迷ったらこれ!判定フロー🧭✨
変更を見たら、順番にこれだけ聞けばOKだよ👇😺
-
利用者のコードが壊れる?(ビルド失敗、実行時エラー、意味が変わって動作が変になる…) → Yes なら MAJOR 😱💥
-
壊れないけど、新しい機能が増えた? → Yes なら MINOR ✨🎁
-
機能追加じゃなくて、バグ修正だけ? → Yes なら PATCH 🩹✅
「壊れる」の考え方は「利用者が修正を要求される可能性がある変更」って捉えると判断しやすいよ👀✨ (Livefront)
7.5 TypeScriptでよくある変更パターン集🧩🟦
A. これは PATCH 🩹✨(だいたい安全)
- 内部処理の修正で、公開APIの入出力は同じ
- バグってた挙動を “仕様通り” に戻す(※ただし利用者がバグに依存してたら難しい😵💫)
例(内部だけ修正)👇
// export されてる関数のシグネチャはそのまま
export function parseId(input: string): number {
// バグ: "001" が 1 にならない…などを修正するイメージ
return Number.parseInt(input, 10);
}
SemVer的には「後方互換なバグ修正」は PATCH 🩹 (Semantic Versioning)
B. これは MINOR 🎁✨(増やす・広げる)
- 新しい export を追加(既存はそのまま)
- 任意パラメータを追加(デフォルト値あり)
- 既存機能に @deprecated を付ける(“次で消すよ”の予告)🚧
例(任意パラメータ追加)👇
export function greet(name: string, options?: { emoji?: boolean }) {
const mark = options?.emoji ? "✨" : "";
return `Hello, ${name}${mark}`;
}
「非推奨を付けたら MINOR」は仕様に明記されてるよ📌 (Semantic Versioning)
C. これは MAJOR 😱💥(壊れる)
- 引数を 必須で追加(呼び出し側が全修正になる)
- 戻り値の型を変える(string→number など)
- export の削除 / 名前変更
- 既存の意味が変わる(同じ引数なのに結果が別物)
例(必須引数追加=壊れる)👇
// 旧: greet(name: string)
// 新: greet(name: string, lang: "ja" | "en") ← 必須が増えた!
export function greet(name: string, lang: "ja" | "en") {
return lang === "ja" ? `こんにちは ${name}` : `Hello, ${name}`;
}
公開APIに後方互換のない変更が入ったら MAJOR 必須だよ😱 (Semantic Versioning)
7.6 0.y.z(0系)ってどう扱うの?🧪🌀
SemVerでは **0.y.z は「初期開発」**扱いで、公開APIは安定してない前提だよ⚠️ つまり「なんでも変わり得る」ゾーン😵💫 (Semantic Versioning)
でも実務では、0系でも “それっぽく” 運用したいよね?🙂 npm の世界では 0.x の x を「壊れる番号」扱いする文化がよくあるよ📦✨ (npm ドキュメント)
おすすめ感覚(0系のとき)👇
- 0.2.3 → 0.2.4:PATCHっぽい🩹
- 0.2.3 → 0.3.0:MAJORっぽい(壊れる可能性強)😱
7.7 package.json の ^ と ~ を理解しよ📦🔧

ここ、超事故ポイント!😇💥 npm の範囲指定は、だいたいこう覚えるとOKだよ👇
-
~1.2.3:1.2 の中で更新OK(パッチ中心)🩹
- 例:>=1.2.3 かつ <1.3.0
-
^1.2.3:1 の中で更新OK(マイナー+パッチ)🎁🩹
- 例:>=1.2.3 かつ <2.0.0
しかも 0系は挙動が違うのが罠!🕳️
- ^0.2.3 は <0.3.0 まで(0.x は “x を壊れ番号扱い” みたいな感覚)
- ^0.0.3 は <0.0.4 まで(ほぼ固定)
このルールは npm の SemVer ドキュメントにまとまってるよ✅ (npm ドキュメント)
例(依存指定)👇
{
"dependencies": {
"some-lib": "^1.4.2",
"tiny-lib": "~2.3.0"
}
}
7.8 TypeScriptならでは:型も契約だよ🟦🤝
TypeScriptのライブラリって、型定義がそのまま契約になりやすいよね✨ だから「動く」だけじゃなくて「型が通る」も大事!
たとえば、次みたいな変更は 利用者の型チェックが落ちることがある😵💫
- 型を “狭める/変える”(string → number とか)
- 既存プロパティを削除 / 名前変更
- ユニオン型の扱いを変えて、今まで通ってたコードが通らなくなる
実際、TypeScript向けツール群でも「型の非互換は breaking」として整理されてるよ📌 (TypeScript ESLint)
7.9 (最新トピック)TypeScript本体は “厳密SemVer” じゃない点も知っとこ🧠⚠️
ライブラリは SemVer で運用するのが基本だけど、足元のツール(TypeScriptコンパイラ)は事情がちょい複雑🍀 公式の Breaking Changes ページが継続的に更新されていて、バージョンアップで型チェック挙動が変わり得るのが分かるよ🧯 (GitHub)
さらに 2025年12月の公式ブログでは、**TypeScript 6.0 は 7.0 への “橋渡し”**で、6.1は出さない予定(必要ならパッチのみ)…みたいな方針も出てるよ📣 (Microsoft for Developers)
👉 つまり、依存の更新では「SemVerだから絶対安心」と思い込まず、CHANGELOG/リリースノートを見る習慣が超大事だよ🙂📚
7.10 ミニ演習:SemVer判定クイズ🎮✨(10問)
次の変更、どれを上げる?(前提:1.0.0以上、公開APIがあるプロジェクト)🔢
- 内部処理のバグ修正。公開APIは変わらない。
- 新しい export 関数を追加(既存はそのまま)。
- 既存関数に必須引数を1つ追加。
- 戻り値の型を string → number に変更。
- 既存型のプロパティを optional → required に変更。
- 既存機能に @deprecated を付けた(まだ消してない)。
- @deprecated にしてた関数を削除した。
- JSONレスポンスに “新しい任意フィールド” を追加(古いクライアントは無視できる想定)。
- エラーコードの値を変更(利用者がコードで分岐してる可能性あり)。
- README を整えた(コードは同じ)。
解答✅✨
- PATCH 🩹
- MINOR 🎁
- MAJOR 😱
- MAJOR 😱
- MAJOR 😱(型契約が壊れる)
- MINOR 🚧(非推奨は MINOR) (Semantic Versioning)
- MAJOR 💥
- だいたい MINOR 🎁(ただし “必須化” したら危険)
- 多くは MAJOR 😱(挙動・意味が変わる系)
- PATCH(か、リリースしないでもOK)📝
7.11 AI活用コーナー🤖✨(そのままコピペでOK)
- 「次の変更一覧を SemVer(MAJOR/MINOR/PATCH)で分類して。理由も短く」🧠
- 「この変更、利用者コードが壊れる可能性を3パターン挙げて」😱
- 「破壊変更を避けるための代替案(段階移行・非推奨)を提案して」🪜🚧
- 「CHANGELOG 用に Added/Changed/Deprecated/Removed/Fixed/Security で書き分けて」📰✨
7.12 リリースノート&CHANGELOGの型📰📚
SemVerは「番号で伝える」だけど、実務では 文章で伝えるのがセットだよ✍️✨ 有名な型として Keep a Changelog では、変更をこう分類するのがおすすめされてるよ👇
- Added / Changed / Deprecated / Removed / Fixed / Security (Keep a Changelog)
あと GitHub のリリースノート自動生成も便利! タグを切って「Generate release notes」できたり、SemVerに基づいて “latest release” が自動で決まる挙動もあるよ📌 (GitHub Docs)
まとめ✨🎀
- SemVerは「公開APIがどう変わったか」で決める🚪
- 壊したら MAJOR / 増やしたら MINOR / 直したら PATCH🩹🎁😱
- 非推奨を付けたら MINOR(地味に重要!)🚧
- npm の ^ / ~ と 0系のクセを理解すると事故が激減📦✨ (npm ドキュメント)
- TypeScriptは 型=契約になりやすいから、型変更は breaking 判定になりがち🟦🤝 (TypeScript ESLint)