😉

【TypeScript】unknown と anyを比較してみる

2025/02/02に公開

TypeScript を使っていて、catch (error: any) に ESLint エラーが出たことはありませんか?

any ならなんでも受け取れるし、問題ないのでは?」 と思うかもしれませんが、それが落とし穴!

本記事では、unknownany の違いや、エラーハンドリングでの instanceof Error の重要性について解説します。


any を使うと危険?

try {
  throw new Error("Something went wrong!");
} catch (error: any) { // ❌ 型チェックなし
  console.log(error.message); // 実行時エラーの可能性
}

any はどんな型の値でも許容しますが、その分型チェックが行われず、

  • nullundefined を受け取った場合 → error.message でクラッシュする可能性あり
  • stringnumber を受け取った場合 → 意図しない挙動になる

といったリスクがあります。


unknown を使うと型安全!

try {
  throw new Error("Something went wrong!");
} catch (error: unknown) {  // ✅ より安全な方法
  if (error instanceof Error) {  // `Error` 型かどうかチェック
    console.log(error.message);  // 安全にアクセス可能
  } else {
    console.log("Unknown error occurred");
  }
}

🔹 unknown のメリット

  • 型チェックが必須 なので、不正なアクセスを防げる
  • instanceof Error を使うことで、Error 型であることを保証できる

unknown を使うことで、エラーハンドリング時のバグを減らせます!


instanceof Error って何?

instanceof は JavaScript の標準演算子で、オブジェクトが特定のクラスのインスタンスかどうかをチェックできます。

class Animal {}
class Dog extends Animal {}

const dog = new Dog();
console.log(dog instanceof Dog);    // ✅ true(Dogのインスタンス)
console.log(dog instanceof Animal); // ✅ true(Animalのサブクラス)
console.log(dog instanceof Object); // ✅ true(すべてのオブジェクトは Object のインスタンス)
console.log(dog instanceof Array);  // ❌ false(Arrayではない)

エラーハンドリングでは、error instanceof Error を使うことで、エラーオブジェクトが Error 型であることを TypeScript に保証させることができます。

try {
  throw new Error("Something went wrong!");
} catch (error: unknown) {
  if (error instanceof Error) {
    console.log(error.message); // ✅ 安全にアクセスできる
  }
}

instanceof の注意点

1️⃣ nullundefined には使えない

console.log(null instanceof Object);  // ❌ TypeError
console.log(undefined instanceof Object);  // ❌ TypeError

2️⃣ 別の JavaScript 環境(iframeなど)では正しく動作しないことがある

const array = new iframeWindow.Array();
console.log(array instanceof Array);  // ❌ false(別の JavaScript 環境のため)

この場合は Object.prototype.toString.call(obj) === "[object Array]" のような方法でチェックするのが安全です。


🎯 まとめ

any は型チェックなしで危険 🚨
unknown を使うと型安全!
instanceof Error でエラーオブジェクトの型を保証
instanceof には nulliframe の問題点もある

TypeScript で安全なエラーハンドリングをするなら、

catch (error: unknown) {
  if (error instanceof Error) {
    console.log(error.message);
  }
}

このパターンを使うのがベストです!

TypeScript でのエラーハンドリング、ぜひ試してみてください! 🚀

Discussion