typeofで絞り込む
union のままでは片方の機能が使えない
union 型の値には、並べたすべての型に共通する操作しかできません。
function label(updated: string | number): string {
return updated.trim();
// エラー Property 'trim' does not exist on type 'string | number'.
}trim は文字列の機能なので、数値かもしれない値には使わせてもらえません。使いたければ、文字列であることを先に確かめる必要があります。
typeof で確かめると型が狭まる
typeof は JavaScript にもある演算子で、値の種類を文字列で返します。TypeScript はこの判定を読み取って、分岐の中で型を狭めてくれます。
function label(updated: string | number): string {
if (typeof updated === "string") {
return updated.trim();
}
return updated + "日前";
}if の中では updated が string に確定しているので trim が使えます。そして if を抜けたあとは、残った number に確定します。可能性を消していくこの働きを絞り込みと呼びます。英語では narrowing です。
絞り込みに使える文字列
typeof が返す値のうち、この段階で使うのは次の 3 つです。文字列なら "string"、数値なら "number"、真偽値なら "boolean" が返ります。
function toText(value: string | number | boolean): string {
if (typeof value === "boolean") {
return value ? "公開" : "下書き";
}
if (typeof value === "number") {
return value + "件";
}
return value;
}最後の return value は、string だけが残っているので型注釈どおりに通ります。分岐で消し切ると、注釈を足さなくても辻褄が合うようになります。
消し忘れると教えてくれる
絞り込みが足りないと、その場でエラーになります。
function toText(value: string | number): string {
if (typeof value === "number") {
return value + "件";
}
return value.toFixed(1);
// エラー Property 'toFixed' does not exist on type 'string'.
}数値を先に返してしまったあとに数値の機能を使おうとしたので止まりました。書いた分岐と使っている機能がずれていることを、型が指摘してくれています。
手を動かす
演習では、作品の更新情報を受け取ってラベルを作ります。日付の文字列で来ることも、何日前かの数値で来ることもあります。typeof で分けて、それぞれに合った文字列を返してください。
要件
updatedは文字列と数値のどちらも受け取れる型にする- 文字列のときは前後の空白を取り除き、うしろに半角スペースと
更新を付ける - 数値のときは
N日前に更新の形で返す - 振り分けには
typeofを使う
入出力例
updatedLabel("2026-08-01") → "2026-08-01 更新"
updatedLabel(" 2026-07-20 ") → "2026-07-20 更新"
updatedLabel(3) → "3日前に更新"
updatedLabel(0) → "0日前に更新"
updatedLabel(14) → "14日前に更新"ヒント
編集 LuaGate編集部