typeofを用いたデータ型判定の基本と応用をわかりやすく解説

スポンサーリンク
スポンサーリンク
amazon
スマイルSALE
--:--:--
~
ad. 価格範囲を指定して商品を探せます

typeofの概要

データ型の判定 JavaScript演算子

typeof

概要 typeof(タイプオブ)は、指定した式や変数の「未評価のデータ型」を判定し、その結果を定義済みの小文字の文字列(例: "string" や "number")として返却する単項演算子です。
動的型付け言語であるJavaScriptにおいて、関数が受け取った引数の型を安全に識別し、ランタイムエラー(予期せぬ型ミスマッチによるクラッシュ)を未然に防ぐための最も基本的な型チェック手段として利用されます。

わかりやすく説明 typeofは、変数や値に対して「あなたはいま、どんな種類のデータ型(文字、数字、オブジェクトなど)になっていますか?」と問いかけて、その正体を文字で教えてもらうための演算子です。

  • 演算子であるため、typeof(value) のような関数風の記述だけでなく、typeof value のように括弧を省略した記述も可能です。
  • 返される値は、ECMAScript仕様で厳格に定められた9種類("undefined", "object", "boolean", "number", "bigint", "string", "symbol", "function", および環境固有のホストオブジェクト型)の文字列のいずれかになります。
  • プリミティブデータ型の判定には無類の強さを誇りますが、オブジェクトや配列、特殊な値(nullなど)を扱う際にはJavaScriptの歴史的経緯に基づくいくつかの注意点が存在します。

typeofの基本的な使い方

typeof が返す文字列は、完全に小文字で統一されています。実際の各データ型に対する評価結果は以下の通りです。

// 1. プリミティブデータ型の判定
console.log(typeof "Hello");     // 出力: "string"
console.log(typeof 42);          // 出力: "number"
console.log(typeof true);        // 出力: "boolean"
console.log(typeof undefined);   // 出力: "undefined"
console.log(typeof Symbol("id"));// 出力: "symbol" (ES2015以降)
console.log(typeof 10n);         // 出力: "bigint" (ES2020以降)

// 2. 構造化・参照データ型の判定
console.log(typeof {});          // 出力: "object"
console.log(typeof []);          // 出力: "object" (⚠️配列もオブジェクトの一種とみなされる)
console.log(typeof function() {}); // 出力: "function" (構造上はオブジェクトだが個別に識別される)

// 3. 特殊なケース
console.log(typeof null);        // 出力: "object" (⚠️仕様上の歴史的なバグ)
  • 文字列、数値、真偽値などの基本プリミティブ型は直感通りの文字列が返ります。
  • 関数(Function)はオブジェクトの一種ですが、typeof は特別に "function" という独自の文字列を返してくれるため、コールバック関数の安全チェックに非常に便利です。

typeofの応用例(関数の引数チェックと多態的な処理)

受け取る引数の型によって処理を柔軟に切り替える(ポリモーフィズム的な)防衛コーディングのパターンです。

// 引数の型に応じてフォーマットを柔軟に切り替える関数
function formatPadding(value) {
    // 文字列が渡されたらそのまま両端をスペースで囲う
    if (typeof value === "string") {
        return `[ ${value.trim()} ]`;
    }
    
    // 数値が渡されたら指定された文字数のスペースを生成する
    if (typeof value === "number") {
        return " ".repeat(value);
    }
    
    // それ以外の予期せぬ型はエラーとして弾く
    throw new TypeError("引数には文字列または数値を指定してください。");
}

console.log(formatPadding("Welcome")); // 出力: "[ Welcome ]"
console.log(formatPadding(4).length);  // 出力: 4 (4文字分の空白スペース)
// formatPadding(true);                // 🛑 TypeErrorが発生しバグを早期検知

注意点

  • typeof null が "object" になる歴史的バグ: JavaScriptの最初の実装におけるメモリ上のデータ表現(型タグの割り当て)のバグが原因で、null の判定結果が "object" になってしまいます。この挙動はすでに数多くの既存Webサイトのコードに埋め込まれてしまっているため、互換性を崩さないよう、現在も仕様としてあえて修正されずに残されています。
    // ⚠️ nullを安全にチェックするための正しい防衛コード
    const targetData = null;
    
    if (targetData && typeof targetData === "object") {
        // ⭕ targetDataが「nullではなく」、かつ本物のオブジェクトである場合のみ通る
        console.log("安全にオブジェクトのプロパティにアクセスできます。");
    } else {
        console.log("データは空、またはオブジェクトではありません。"); // こちらが実行される
    }
    
  • 配列(Array)を識別できない問題: typeof [] は単に "object" を返すため、通常のオブジェクト({})と配列を区別できません。配列かどうかを正確に知りたい場合は、ES5で追加された専用静的メソッド Array.isArray() を使用します。
    // ⚠️ 配列の識別ミスを防ぐアプローチ
    const list = [1, 2, 3];
    
    console.log(typeof list === "object"); // true ❌ これでは普通のオブジェクトか配列か分からない
    console.log(Array.isArray(list));      // true ⭕ 配列であることを100%確実に特定
    
  • NaN(Not-a-Number)の型評価: 計算エラーなどで発生する NaN(非数)に対し typeof を実行すると、文字通り「数値ではない」という名前のステータスであるにもかかわらず、データ型としては "number" が返ってきます。
    // ⚠️ NaNの型チェックに潜む罠と対策
    const invalidResult = 10 / "文字列"; // 計算不能で NaN になる
    
    console.log(typeof invalidResult); // "number" ❌ 数値として判定されてしまう
    console.log(Number.isNaN(invalidResult)); // true ⭕ 本当に有効な数値データか安全に判定
    

よくある質問

Q: typeof 演算子を使用するとき、後ろの対象を括弧で囲む typeof(value) と、スペースで区切る typeof value に機能的な違いはありますか?
A: 機能やパフォーマンス上の違いは一切ありません。JavaScriptにおいて typeof は関数ではなく「演算子」であるため、スペースで区切る typeof value が本来のスマートな書き方です。
ただし、特定の計算式の「計算結果の型」を判定したい場合は、演算の優先順位を明確にするために括弧で囲む必要があります。

// 括弧が必要になる応用パターン
console.log(typeof "Hello" + 10);   // 出力: "string10" ❌ (typeof "Hello" が先に評価され、文字列結合される)
console.log(typeof ("Hello" + 10)); // 出力: "string"   ⭕ (計算した結果全体の型を安全に判定)
Q: クラスから生成したカスタムインスタンスの型(どのクラス由来か)を typeof で特定することはできますか?
A: できません。自作したクラスや組み込みのクラス(Date や `RegExp` など)から生成されたインスタンスは、`typeof` を通すと一律で "object" に丸められてしまいます。
インスタンスの具体的な生成元(由来クラス)を特定・検証したい場合は、`typeof` ではなく **instanceof 演算子** を使用してください。

// クラスインスタンスの正確な判定コード例
class User {}
const admin = new User();

console.log(typeof admin);          // "object" ❌ クラス名までは判別できない
console.log(admin instanceof User); // true     ⭕ Userクラスのインスタンスであることを正確に証明

まとめ

typeof演算子は、変数が保持している現在の生データ型を文字列として取り出し、柔軟なランタイムチェックを行うための最も軽量なインスペクション命令です。

  • 文字列、数値、関数といった主要なプリミティブ型や実行可能オブジェクトを瞬時に見分ける用途に最適です。
  • null が "object" を返すバグや、配列・NaN の誤認リスクといった言語仕様上の境界条件を正確に把握し、必要に応じて Array.isArray() などの専門APIを織り交ぜて防衛してください。
  • 判定結果の文字列はすべて「完全小文字(例: "string")」で返却されるため、タイポによる条件分岐のすり抜けが起きないよう厳密等価演算子(===)を用いた手堅い比較を心がけましょう。