22
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TypeScript における any と unknown の使い分け

22
Last updated at Posted at 2026-04-10

TypeScript で「型がはっきり分からない値」を扱うとき、anyunknown が候補に挙がります。
どちらも何でも代入できる型ですが、代入した後に何ができるかがまったく違います。
この記事では両者の違いと、使い分けを整理します。

any — 型チェックを無効化する型

any を付けた値には、どんな操作でもエラーなく通ります。

const value: any = "hello";

value.toUpperCase();   // OK
value.notFoundMethod(); // OK(実行時エラー)
value.foo.bar.baz;     // OK(実行時エラー)

TypeScript は何も警告してくれません。
つまり any「分からないけど、何でもできることにする」 型です。

any の注意点

any が厄介なのは、関数の戻り値を通じて他の変数にも広がる 点です。
1 箇所の any がコードベース全体に波及し、型チェックが機能しない領域がじわじわ広がります。

function getConfig(): any {
  return JSON.parse("...");
}

const config = getConfig();  // config も any
const name = config.user.name; // name も any

unknown — 確認するまで触らせない型

unknown も何でも代入できますが、そのままでは操作できません

const value: unknown = "hello";

value.toUpperCase(); // コンパイルエラー

使うには、型を絞り込む必要があります。

if (typeof value === "string") {
  value.toUpperCase(); // OK
}

unknown「分からないので、確認できるまで触らせない」 型です。

型の絞り込み方

unknown を扱うための代表的な絞り込み方法を整理します。

typeof によるプリミティブの判定

function formatValue(value: unknown): string {
  if (typeof value === "string") return value;
  if (typeof value === "number") return value.toString();
  return "不明な値です";
}

instanceof によるクラスの判定

try {
  // 何らかの処理
} catch (error: unknown) {
  if (error instanceof Error) {
    console.error(error.message);
  }
}

ユーザー定義型ガード

オブジェクトの構造を検証したいときは、型ガード関数を使います。

type User = { name: string; age: number };

function isUser(v: unknown): v is User {
  return (
    typeof v === "object" &&
    v !== null &&
    "name" in v &&
    typeof (v as User).name === "string" &&
    "age" in v &&
    typeof (v as User).age === "number"
  );
}

const data: unknown = await fetchSomeData();
if (isUser(data)) {
  console.log(data.name); // OK: User として扱える
}

APIレスポンスのように構造が不確定なデータに対しては、この方法が実用的です。

※ただし、ユーザー定義型ガードを自分で書くのは危険です。型述語 v is T の中身が間違っていてもコンパイラは検知してくれず、型定義を変えても追従漏れに気づけません。基本的にはスキーマライブラリ(Zod / Valibot など)を使うか、TypeScript の型推論に任せる方が安全です。
参考:
https://zenn.dev/yumemi_inc/articles/ts-avoid-hand-writing-type-guards

unknown が活きる場面

外部からのデータ取得

const response: unknown = await fetchSomeData();

型ガードで確認してから使えば安全です。

catch のエラー

TypeScript では throw に何でも渡せるため、catch で受け取る値は Error とは限りません。

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

汎用的な関数の入力

引数の型を限定したくないが、安全に扱いたい場面で有効です。

any を使ってよい場面

any は禁止するべきものではなく、スコープを限定して使う のがポイントです。

  • 型定義がない古いライブラリを一時的に扱う
  • JavaScript からの段階的な移行中
  • 型で表現しきれず、一時的に逃がしたい

ただし、入口で any にしたらすぐ具体的な型に変換し、外に漏らさないことが大事です。

// ❌ any のまま使い回す
const data: any = getLegacyData();
doSomething(data); // data の any が伝播する

// ✅ 早めに型を付ける
const raw: any = getLegacyData();
const data: UserConfig = raw as UserConfig; // ここから先は型が効く

避けたいアンチパターン:ダブルアサーション

const value = someData as unknown as TargetType;

as unknown as T は型システムを完全にバイパスする書き方です。
本来通らない型変換を無理やり通すので、実行時エラーの温床になります。
これを書きたくなったら、型設計自体を見直すサイン と考えた方がよいです。

まとめ

any unknown
代入 何でも入る 何でも入る
操作 何でもできる 絞り込まないとできない
型チェック 無効化される 維持される
伝播 する(危険) しない

基本方針は 迷ったら unknown

any で型情報を捨てるより、unknown で受けて絞り込む方が TypeScript の恩恵を活かせます。
any を見かけたら「これは本当に any である必要があるか?」を一度考えるだけで、コードの安全性はかなり変わります。

22
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?