narrowing 型のナローイングの基礎(真値性と代入可能性を含む)
最終更新:2026-10-22
narrowing 型のナローイングの基礎(真値性と代入可能性を含む)
ユニオン型は複数の可能性を1つの変数にまとめます。使う前には、その変数が今どの型なのかを「確かめる」必要があります。広い型を具体的な型へ縮めるこの過程をナローイングと呼びます。TypeScriptはif、switch、真値判定などの制御フローを解析し、変数を対応する分岐の型へ自動的にナローイングます。その後で初めて、その分岐にしかないプロパティに安全にアクセスできます。
| グループ | ナローイングとアサーション |
|---|---|
| 種類 | 構文 |
| strict モード | 不要 |
ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。
📝 構文
function handle(value: string | number | null) {
if (value == null) return; // null/undefined を除外してナローイング
if (typeof value === "string") {
value.toUpperCase(); // ここで value は string にナローイング済み
} else {
value.toFixed(2); // ここで value は number にナローイング済み
}
}
⚙️ パラメータ
| == null | 緩やかな等価(== null)判定は null と undefined を同時に取り除ける、最もよく使われる空値のナローイングの書き方です |
|---|---|
| truthiness | if (value) のような真値チェックは、null、undefined、0、""、false、NaN を一度に取り除きます |
戻り値:戻り値はありません。ナローイングはコンパイル時の制御フロー分析であり、実行時コードは一切生成しません。
▶ サンプル
下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:
出力:
Hello, guest
Hello, guest
Hello, anonymous
Hello, Ada (length 3)
(トランスパイル後の実行出力。各分岐内で name.length に安全にアクセスできるのは、tsc が name を string に絞り込んでいるからです。実行時に見えるのは値そのものだけです)
💡 ポイント
ℹ️ 説明 ナローイングは完全にコンパイル時の動作です。TS はコードの実行パスに沿って型を追跡し(制御フロー分析)、トランスパイル後の JS に「ナローイング用のコード」は一切含まれません。
⚠️ 注意 真値チェックは正当な falsy 値まで巻き込みます。0、""、false も if (value) で除外されます。0 が有効な業務値(価格や数量など)である場合は、value != null や明示的な typeof 判定を使いましょう。
💡 ヒント ナローイングはローカル変数と const に対して最も信頼できます。オブジェクトのプロパティは関数呼び出しを挟むとナローイングが失効することがあります(TS は関数がそれを書き換えたかどうか知り得ません)。その場合はプロパティを先にローカル変数へ取り出すか、型ガード関数を使いましょう。
🏷️ 関連ナローイングとアサーション
💡 関連ケース
ケースは今後追加予定です。
📚 関連チュートリアル
❓ よくある質問
Q ナローイングと型アサーション(as)の違いは何ですか?
A ナローイングは書いたチェックからコンパイラが自動的に推論するため、チェックと型が一致しています。アサーションは手動で型を「宣言」するもので、コンパイラは検証しません。ナローイングが使えるならアサーションは避けるべきです。間違ったアサーションでもコンパイラは止めてくれません。
Q 先に if (!obj.flag) と判定したのに、後で obj.flag が undefined のままのことがあるのはなぜですか?
A プロパティやメソッド呼び出しなど「副作用があり得る」アクセスに対して、TS はナローイングを長く保持しません。間にあるどの関数呼び出しもそれを書き換える可能性があります。安全なのは値を const のローカル変数に取り出してから判定することです。
Q null と undefined を1回の判定で両方排除できますか?
A できます。value == null(緩やかな等価)は両方を一度に除外します。value != null を使った逆の判空も可能です。厳密等価 === なら2回書く必要があります(=== null と === undefined)。