🗂

TypeScript で any 型より unknown 型を使うべき理由

に公開

TypeScript で型定義がどうにもならないときに、とりあえず any を使ってませんか?any 型は便利な逃げ道ですが型安全性を完全に放棄する危険な選択です。

そこで使いたいのが unknown 型です。同じように「何でも受け入れる」役割を果たしながら、TypeScript の型システムの恩恵を受けることができます。

この記事では、なぜ unknown 型が any 型より優れているのかを、実際のコード例と共に解説します。

any 型が引き起こす 3 つの問題

TypeScript の型チェック機能が完全に無効化される

any 型を使うと、TypeScript が型安全性を放棄して何でも許可してしまいます。

function fetchUserData(): any {
  return {
    name: "田中太郎",
    age: 25,
    email: "tanaka@example.com",
  };
}

const user = fetchUserData();

// ❌ 存在しないプロパティでもエラーなし
console.log(user.username); // undefined(意図しない動作)

// ❌ 間違ったメソッド呼び出しでもエラーなし
user.getName(); // 実行時エラー:TypeError

// ❌ 不正な演算でもエラーなし
const result = user * 2; // NaN(予期しない結果)

本番環境で実行時エラーが突然発生する

コンパイル時にエラーを検出できないため、ユーザーが実際に使用するタイミングでアプリケーションがクラッシュします。

// 本番環境で起こりがちなエラー例
function processUserAction(action: any) {
  // 開発時は動作していたが...
  return action.type.toUpperCase(); // actionがnullの場合にエラー
}

// 実行時エラー:Cannot read property 'toUpperCase' of null

IDE の型補完とエラー検出が機能しない

any 型では IDE が型情報を認識できないため、開発効率が大幅に低下します。

  • 自動補完が効かない
  • 間違ったプロパティ名でもエラー表示されない
  • リファクタリング時の影響範囲が把握できない

unknown 型が型安全性を実現する仕組み

TypeScript の型階層で最上位に位置する安全な型

unknown 型は型システムの管理下で全ての型を受け入れる最上位の型です。

// TypeScript の型階層
/*
      unknown (最上位:全てを安全に受け入れ)
         ↓
    ┌────┼────┐
string  number  object  boolean
    ↓     ↓      ↓      ↓
具体的な値の型("hello", 42, など)
    ↓     ↓      ↓      ↓
  never  never   never  never (最下位)
*/

型ガードによる段階的な型の絞り込み

unknown 型の特徴としてあるのは、型チェック前は何もできないことです。

function processData(data: unknown) {
  // ❌ 型チェック前はプロパティアクセス不可
  console.log(data.name); // コンパイルエラー

  // ✅ 型ガードで安全性を確保してから使用
  if (typeof data === "object" && data !== null && "name" in data) {
    console.log((data as { name: string }).name); // OK
  }
}

実行時エラーをコンパイル時に事前検出

最も重要な違いは、危険なコードをコンパイル段階で防げることです。

// any型:危険なコードもコンパイル通過(実行時エラー)
function dangerousExample(data: any) {
  return data.someObject.property; // 実行時エラーの可能性
}

// unknown型:危険なコードはコンパイルエラー
function safeExample(data: unknown) {
  // return data.someObject.property; // TS2339: コンパイルエラー

  // 型ガードで安全に処理
  if (isValidData(data)) {
    return data.someObject.property; // 安全
  }
}

まとめ:型安全性がもたらす開発効率の向上

any 型と unknown 型の違い

観点 any 型 unknown 型
型システムとの関係 完全に脱出 システム内で管理
コンパイル時チェック 無効 有効(事前にエラー検出)
実行時エラー 発生しやすい 型ガードで防げる
コード補完 効かない 型チェック後に有効
保守性 著しく低下 高く保たれる

「型がわからないから any」→「型がわからないからこそ unknown

この考え方の転換が、型安全で保守しやすい TypeScript コードへの第一歩!

TypeScript の真の力を引き出すために、 unknown 型を積極的に活用してみてください。確実に、より安全で保守しやすいものになるはずです!

Discussion