1if と else で型が変わる
typeof の確認を通ると、if のブロック内では string、else 側では number として扱われる絞り込みの最小例です。それぞれのブロックで型専用のメソッドが使えることを確かめましょう。
function showType(value: string | number): void {
if (typeof value === "string") {
// ここでは value は string なので toUpperCase が使える
console.log("文字列です: " + value.toUpperCase());
} else {
// ここでは value は number なので toFixed が使える
console.log("数値です: " + value.toFixed(2));
}
}
showType("typescript");
showType(19.5);
2文字列か数値かを数値に統一する
「"3.14" のような数値の文字列か、数値そのもの」を受け取り、必ず number にして返す変換関数です。フォーム入力や設定値など、型が揺れる入力を入り口で統一する実務の頻出パターンです。
function toNumber(input: string | number): number {
if (typeof input === "string") {
return parseFloat(input); // string に絞り込まれている
}
return input; // ここでは number に絞り込まれている
}
console.log(toNumber("3.14") + 1);
console.log(toNumber(10) + 1);
console.log(toNumber("100") * 2);
3早期 return で残りの型に絞る
if の中で return すると、それ以降のコードでは残りの型に絞り込まれたままになります。例外的なケースを先に返して、本筋の処理をネストなしで書ける読みやすいスタイルです。
function printScore(score: number | string): void {
if (typeof score === "string") {
console.log("未採点: " + score);
return; // ここで抜けると…
}
// ここから先は number に絞り込まれたまま
console.log("得点: " + score.toFixed(0));
console.log(score >= 60 ? "合格" : "不合格");
}
printScore(82.5);
printScore("採点中");
43つの型を順番に絞り込む
候補が3つ以上でも、typeof の確認を重ねるたびに残りの候補が減っていきます。最後の return の時点では boolean しか残っていない、という消去法をコンパイラが追いかけてくれます。
function stringify(value: string | number | boolean): string {
if (typeof value === "string") {
return value;
}
if (typeof value === "number") {
return value.toFixed(1);
}
return value ? "yes" : "no"; // 残るのは boolean だけ
}
console.log(stringify("hello"));
console.log(stringify(3.14159));
console.log(stringify(true));
5JSON データの中身を検証して使う
JSON.parse の結果は中身が保証できないので unknown で受け、typeof で確認してから使います。外部 API やファイルから来たデータを安全に取り込む、実務でそのまま使える型チェックの形です。
// JSON.parse の結果は unknown で受けるのが安全
function readCount(jsonText: string): number {
const parsed: unknown = JSON.parse(jsonText);
if (typeof parsed === "number") {
return parsed; // 確認できたので number として返せる
}
console.log("数値ではないデータが届きました");
return 0;
}
console.log(readCount("42"));
console.log(readCount("[1,2]"));