【TypeScript】TS2304の原因と解決方法|Cannot find nameを完全解説

【TypeScript】TS2304の原因と解決方法|Cannot find nameを完全解説 TypeScript

TypeScriptで開発をしていると、突然ターミナルやエディタに TS2304 というエラーが表示されることがあります。Cannot find name 'X' というメッセージとともに、コンパイルが止まってしまった経験はありませんか?

TS2304は「名前が見つからないエラー」を意味し、TypeScriptコンパイラがあなたのコード中にある識別子(変数名・関数名・型名など)を解決できないときに発生します。単純なタイポ(スペルミス)から、import忘れ、型定義ファイルの未インストール、tsconfig.jsonの設定不備、テスト・React・Node.jsなどの環境固有の問題まで、非常に幅広い原因で発生するエラーです。

この記事では、TS2304エラーを発生パターン別に徹底分類し、それぞれについて実際のエラーメッセージNGコード原因の解説OKコード(修正例)を掲載します。エラーが出たらこの記事を辞書的に参照すれば、すぐに原因を特定し解決できるはずです。

この記事で学べること

  • TS2304エラーメッセージの読み方意味
  • 変数名のタイポ宣言前の参照スコープ外アクセスなど基本パターン
  • import / export 関連の TS2304(named import・default import・循環参照・パスエイリアス)
  • 型定義ファイル(.d.ts)関連の TS2304(@types・declare global・typeRoots)
  • DOM API での TS2304(document / window / HTMLElement)
  • Node.js 固有の TS2304(process / __dirname / Buffer / require)
  • テストフレームワークでの TS2304(Jest / Vitest の describe / it / expect)
  • React / JSX での TS2304(React・useState・カスタムコンポーネント)
  • グローバル変数・環境変数での TS2304(window.XXX・process.env)
  • tsconfig.json の設定で解決する TS2304(lib・types・include・paths)
  • 実務でよくあるTS2304パターン10選

前提知識:この記事はTypeScriptの基本的な構文を理解している方を対象としています。型の基本から学びたい方は【TypeScript】型の書き方 完全入門を先にお読みください。

スポンサーリンク
  1. TS2304エラーとは?
    1. エラーメッセージの読み方
    2. なぜTS2304エラーが発生するのか
    3. TS2304 と似たエラーコードとの違い
  2. 基本的なケースと解決方法
    1. 変数名・関数名のタイポ(スペルミス)
    2. 大文字・小文字の間違い
    3. 宣言前に参照している(TDZ: Temporal Dead Zone)
    4. import の忘れ
    5. スコープ外の変数にアクセス
  3. import / export 関連のTS2304
    1. named import の名前間違い
    2. default import vs named import の混同
    3. 循環参照(Circular Dependency)による問題
    4. パスエイリアス(@/ ~)の設定不備
    5. .ts 拡張子の有無による問題
  4. 型定義(.d.ts)関連のTS2304
    1. @types パッケージの未インストール
    2. グローバル型の定義方法(declare global)
    3. カスタム型定義ファイルの作成
    4. tsconfig.json の typeRoots / types 設定
    5. ambient declaration(declare)の使い方
  5. DOM API でのTS2304
    1. document / window が見つからない
    2. HTMLElement / Event 等のDOM型
    3. Node.js 環境で DOM を参照した場合
    4. tsconfig.json の lib 設定の選び方
  6. Node.js 固有のTS2304
    1. process / __dirname / __filename / Buffer / require
    2. ES Modules での __dirname / __filename
    3. global / globalThis の使い方
  7. テストフレームワークでのTS2304
    1. Jest: describe / it / expect / jest
    2. Vitest: vi / describe / expect
    3. tsconfig の include 設定の確認
  8. React / JSX でのTS2304
    1. React が見つからない(React 17+ の jsx transform)
    2. カスタムコンポーネント名の大文字/小文字
    3. useState / useEffect の import 忘れ
  9. グローバル変数・環境変数でのTS2304
    1. window にカスタムプロパティを追加する場合
    2. process.env の型定義
    3. Vite の環境変数(import.meta.env)
  10. tsconfig.json の設定で解決するTS2304
    1. lib オプション
    2. include / exclude の設定ミス
    3. moduleResolution の選択
    4. baseUrl / paths の設定
    5. tsconfig の設定チェックリスト
  11. 実務でよくあるTS2304パターン10選
    1. パターン1: ライブラリの型定義が不足している
    2. パターン2: グローバル変数(jQuery の $ 、Google Analytics の gtag)
    3. パターン3: Jest / Vitest のテスト関数
    4. パターン4: Node.js の process / __dirname
    5. パターン5: React の useState / useEffect の import 忘れ
    6. パターン6: tsconfig.json の lib に DOM がない
    7. パターン7: モジュールの拡張子問題
    8. パターン8: monorepo でのパッケージ参照
    9. パターン9: CI/CD 環境での型エラー
    10. パターン10: const enum を isolatedModules で使う
  12. まとめ
    1. TS2304 と関連エラーの違いまとめ
    2. 関連記事

TS2304エラーとは?

TS2304 は TypeScript コンパイラが出す「名前解決エラー」です。コード中で使用された識別子(変数名・関数名・型名・インターフェース名など)がどこにも宣言されていない、またはコンパイラから見える範囲に存在しないと判断されたときに発生します。正式なエラーメッセージは次のとおりです。

error TS2304: Cannot find name ‘X’.

日本語に訳すと「名前 ‘X’ が見つかりません」となります。ここでの ‘X’ は変数名、関数名、型名、インターフェース名など、あらゆる識別子が該当します。TypeScriptコンパイラが「あなたが使おうとしている名前は、現在のスコープや型情報のどこにも定義されていません」と教えてくれているのです。

エラーメッセージの読み方

TS2304のエラーメッセージは、以下のフォーマットに従っています。具体例で構造を確認しましょう。

エラーメッセージの例
src/index.ts:5:1 - error TS2304: Cannot find name 'myVariable'.

5   console.log(myVariable);
                ~~~~~~~~~~

このエラーメッセージは以下のパーツで構成されています。

パーツ 意味
ファイルパス src/index.ts エラーが発生したファイル
行:列 5:1 エラー箇所(5行目の1文字目)
エラーコード TS2304 TypeScriptのエラー番号
Cannot find name ‘X’ myVariable 見つからない識別子の名前

覚え方:「Cannot find name ‘あなたが使おうとした名前‘」— TypeScriptは「その名前、どこにも見つかりません」と言っています。宣言・import・型定義のどれかが不足している可能性が高いです。

なぜTS2304エラーが発生するのか

TypeScriptは静的型付け言語であり、コードを実行する前にすべての識別子が宣言されているかどうかをチェックします。JavaScriptでは未宣言の変数を参照すると実行時に ReferenceError が発生しますが、TypeScriptではコンパイル時にこれを検出し、TS2304として報告します。

TS2304が発生する根本原因は、大きく分けて以下の6つに分類できます。

分類 主な原因 よくある例
1. コードの問題 タイポ・宣言忘れ・スコープ外アクセス consle.log()console.log()
2. import / export import忘れ・名前間違い・パスエイリアス設定不備 import { useState } の書き忘れ
3. 型定義の不足 @types未インストール・declare不足 @types/node のインストール忘れ
4. 実行環境の違い DOM型・Node.js型の利用可否 Node.js環境で document を使用
5. tsconfig.json lib・types・include の設定不備 lib"DOM" が未設定
6. フレームワーク固有 Jest / Vitest / React の型設定 describe / it が見つからない

以降のセクションでは、これらの分類ごとに具体的なパターンを一つずつ詳しく解説していきます。

TS2304 と似たエラーコードとの違い

TS2304と混同しやすいエラーコードがいくつかあります。先に違いを整理しておきましょう。

エラーコード メッセージ 意味
TS2304 Cannot find name 'X' 識別子 X がどこにも宣言されていない
TS2552 Cannot find name 'X'. Did you mean 'Y'? X は見つからないが、似た名前 Y が存在する(タイポの可能性)
TS2307 Cannot find module 'X' モジュール X 自体が見つからない(パス・パッケージの問題)
TS2339 Property 'X' does not exist on type 'Y' 型 Y にプロパティ X が存在しない

注意:TS2552 は TS2304 の「親切版」です。TypeScript がタイポを検出できた場合は TS2552 になり、修正候補を提示してくれます。修正候補がない場合に TS2304 が出ます。

基本的なケースと解決方法

まずは最も基本的なパターンから見ていきましょう。コードそのものに問題があるケースです。TS2304エラーの中で最もシンプルで解決しやすいパターンですが、初心者が最初に遭遇しやすいものでもあります。

変数名・関数名のタイポ(スペルミス)

最も多い原因の一つが、単純なタイプミスです。変数名や関数名を1文字でも間違えると、TypeScriptは「その名前は宣言されていない」と判断してTS2304を出します。

error TS2304: Cannot find name ‘consle’.

NGコード
// 変数名のタイポ
const userName = "田中";
console.log(userNmae);  // TS2304: Cannot find name 'userNmae'

// グローバルオブジェクトのタイポ
consle.log("Hello");  // TS2304: Cannot find name 'consle'

// 関数名のタイポ
function calculateTotal(prices: number[]) {
  return prices.reduce((sum, p) => sum + p, 0);
}
const total = calulateTotal([100, 200]);  // TS2304: Cannot find name 'calulateTotal'

原因:userNmaeuserName のタイポ、consleconsole のタイポ、calulateTotalcalculateTotal のタイポです。TypeScriptは名前を厳密に照合するため、1文字でも違えば「見つからない」と判断します。

OKコード(修正例)
// 正しい変数名を使用
const userName = "田中";
console.log(userName);  // OK

// 正しいグローバルオブジェクト
console.log("Hello");  // OK

// 正しい関数名
const total = calculateTotal([100, 200]);  // OK

ポイント:VS Code などのエディタでは、タイポがあると TS2552(Did you mean ‘X’?)としてスペル候補を提示してくれることがあります。エディタの赤い波線と提案メッセージを確認しましょう。

大文字・小文字の間違い

JavaScriptとTypeScriptは大文字・小文字を区別(case-sensitive)します。ArrayarrayStringstring は別の識別子です。

error TS2304: Cannot find name ‘userService’.

NGコード
// TypeScript のプリミティブ型は小文字
const name: String = "田中";  // 動くが非推奨(ラッパーオブジェクト型)

// クラス名と変数名の混同
class UserService {
  getUser() { return { name: "田中" }; }
}
const user = userService.getUser();  // TS2304: Cannot find name 'userService'

原因:UserService(大文字始まり)はクラス名であり、userService(小文字始まり)というインスタンスはどこにも宣言されていません。クラスを使うにはまず new でインスタンス化する必要があります。

OKコード(修正例)
// プリミティブ型は小文字を使う
const name: string = "田中";  // OK

// インスタンスを作成してから使用
const userService = new UserService();
const user = userService.getUser();  // OK

宣言前に参照している(TDZ: Temporal Dead Zone)

letconst で宣言された変数は、宣言文より前のコードでは参照できません。これはTemporal Dead Zone(TDZ / 一時的なデッドゾーン)と呼ばれるJavaScript/TypeScriptの仕様です。

error TS2304: Cannot find name ‘message’.

NGコード
// 宣言前に参照している
console.log(message);  // TS2304: Cannot find name 'message'
const message = "Hello, TypeScript!";

// 関数内でも同様
function greet() {
  console.log(greeting);  // TS2304: Cannot find name 'greeting'
  const greeting = "こんにちは";
}

原因:constlet で宣言した変数は、宣言が実行されるまで「存在しない」扱いになります。これはホイスティング(巻き上げ)されても初期化前はアクセスできないというES2015+の仕様です。TypeScriptはこれをコンパイル時に検出します。

OKコード(修正例)
// 宣言を参照より前に置く
const message = "Hello, TypeScript!";
console.log(message);  // OK

// 関数内でも同様
function greet() {
  const greeting = "こんにちは";
  console.log(greeting);  // OK
}

注意:var で宣言した変数はホイスティングにより宣言前でも undefined として参照できますが、const / let ではTDZにより参照できません。モダンなTypeScriptでは var の使用は避けるべきです。

import の忘れ

他のモジュールで定義された関数や型を使おうとして、import 文を書き忘れているケースです。これは非常によくあるパターンです。

error TS2304: Cannot find name formatDate.

NGコード(src/app.ts)
// import を忘れている!
// import { formatDate } from ./utils;

const today = formatDate(new Date());  // TS2304: Cannot find name formatDate

原因:TypeScriptのモジュールシステムでは、他のファイルで export された識別子を使うには、必ず import 文で明示的に読み込む必要があります。

OKコード(修正例)
import { formatDate } from ./utils;

const today = formatDate(new Date());  // OK

ポイント:VS Code では、未インポートの識別子にカーソルを合わせて Ctrl + .(Quick Fix)を押すと、自動でimport文を追加してくれます。積極的に活用しましょう。

スコープ外の変数にアクセス

ブロックスコープ({ })の中で宣言された変数を、そのブロックの外から参照しようとするとTS2304が発生します。

error TS2304: Cannot find name result.

NGコード
function fetchData(isAdmin: boolean) {
  if (isAdmin) {
    const result = "管理者データ";
  }
  console.log(result);  // TS2304: Cannot find name result
}
OKコード(修正例)
function fetchData(isAdmin: boolean) {
  let result = "一般データ";
  if (isAdmin) {
    result = "管理者データ";
  }
  console.log(result);  // OK
}

import / export 関連のTS2304

モジュールシステムに起因するTS2304は、実務で最も頻繁に遭遇するパターンです。named import の名前間違い、default import との混同、パスエイリアスの設定不備など、多くのバリエーションがあります。

named import の名前間違い

エクスポートされた名前と異なる名前でインポートしようとすると TS2304 が発生します。

error TS2304: Cannot find name ”formatCurrency”.

src/utils.ts(エクスポート側)
export function formatPrice(price: number): string {
  return `¥${price.toLocaleString()}`;
}
NGコード(src/app.ts)
// エクスポート名と異なる名前でインポート
import { formatCurrency } from ''./utils'';
// TS2305 or TS2304
OKコード(修正例)
// 正しいエクスポート名を使う
import { formatPrice } from ''./utils'';
const text = formatPrice(1000);  // OK

// 別名を付けたい場合は as を使う
import { formatPrice as formatCurrency } from ''./utils'';

default import vs named import の混同

default exportnamed export を混同すると、インポート時にエラーが発生します。

NGコード
// default export を named import しようとしている
import { axios } from ''axios'';  // エラー

// named export を default import しようとしている
import formatDate from ''./utils'';  // エラー
OKコード(修正例)
// default export は波括弧なしでインポート
import axios from ''axios'';  // OK

// named export は波括弧付きでインポート
import { formatDate } from ''./utils'';  // OK
エクスポート方法 インポート方法
export default function foo() import foo from ''./mod''(波括弧なし)
export function foo() import { foo } from ''./mod''(波括弧あり)
export { foo, bar } import { foo, bar } from ''./mod''

循環参照(Circular Dependency)による問題

ファイルAがファイルBをインポートし、ファイルBがファイルAをインポートする循環参照が発生すると、一方のファイルでインポートした識別子が undefined になり、TS2304が発生することがあります。

NGコード(循環参照の例)
// --- a.ts ---
import { B } from ''./b'';
export class A { getB() { return new B(); } }

// --- b.ts ---
import { A } from ''./a'';  // 循環参照!
export class B { getA() { return new A(); } }

解決策:共通の型定義を別ファイルに切り出すか、import type を使って型のみのインポートに切り替えます。型のみのインポートは実行時にはコードが生成されないため、循環参照の問題を回避できます。

OKコード(import type で解決)
// --- b.ts ---
import type { A } from ''./a'';  // 型のみのインポート

パスエイリアス(@/ ~)の設定不備

@/ などのパスエイリアスを使ったインポートでエラーが出る場合、tsconfig.jsonpaths 設定が不足しています。

NGコード
// tsconfig.json に paths の設定がない場合
import { UserService } from ''@/services/user'';  // モジュール解決できない
OKコード(tsconfig.json の設定)
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

注意:Vite や webpack を使っている場合、ビルドツール側にも同じエイリアス設定が必要です。tsconfig.json だけでは実行時のパス解決ができません。

.ts 拡張子の有無による問題

TypeScriptのインポートでは、拡張子を付けるかどうかが moduleResolution の設定によって異なります。

moduleResolution による違い
// moduleResolution: "node" の場合
import { foo } from ''./utils'';      // OK(拡張子なし)
import { foo } from ''./utils.ts'';   // エラー

// moduleResolution: "nodenext" の場合
import { foo } from ''./utils.js'';   // OK(.js 拡張子が必要)
import { foo } from ''./utils'';      // エラー

ポイント:moduleResolution: "nodenext" では、TypeScriptファイルでも .js 拡張子を付けてインポートします。これはTypeScriptがコンパイル後のJavaScriptファイルのパスを参照するためです。

型定義(.d.ts)関連のTS2304

外部ライブラリの型定義が不足していたり、グローバル型の宣言が漏れている場合にTS2304が発生します。このセクションでは、@types パッケージ、declare 文、tsconfig.jsontypeRoots / types 設定について解説します。

@types パッケージの未インストール

JavaScriptで書かれたライブラリを TypeScript で使う場合、型定義パッケージ(@types/xxx)のインストールが必要な場合があります。

error TS2304: Cannot find name ”$”.

NGコード
// @types/jquery がインストールされていない
$(".btn").click(() => {
  // TS2304: Cannot find name ''$''
});
解決方法(ターミナル)
# npm の場合
npm install --save-dev @types/jquery

# yarn の場合
yarn add --dev @types/jquery

# pnpm の場合
pnpm add -D @types/jquery
ライブラリ 型定義パッケージ よくある TS2304 の名前
jQuery @types/jquery $, jQuery
Lodash @types/lodash _
Express @types/express Request, Response
Node.js @types/node process, Buffer, __dirname
Jest @types/jest describe, it, expect

グローバル型の定義方法(declare global)

アプリケーション固有のグローバル変数や型を定義するには、declare global を使います。

error TS2304: Cannot find name ”APP_CONFIG”.

NGコード
// グローバルに APP_CONFIG が定義されているが、TypeScript が認識できない
console.log(APP_CONFIG.apiUrl);  // TS2304: Cannot find name ''APP_CONFIG''
OKコード(src/global.d.ts を作成)
// src/global.d.ts
declare const APP_CONFIG: {
  apiUrl: string;
  version: string;
  debug: boolean;
};

これで APP_CONFIG をTypeScriptが認識できるようになります。.d.ts ファイルは tsconfig.jsoninclude パターンに含まれるディレクトリに配置してください。

カスタム型定義ファイルの作成

@types パッケージが存在しないライブラリを使う場合、自分で型定義ファイルを作成する必要があります。

src/types/my-library.d.ts
// 型定義のないライブラリ用のモジュール宣言
declare module ''my-legacy-library'' {
  export function doSomething(input: string): void;
  export const VERSION: string;
}

// 最低限の宣言(any でエクスポート)
declare module ''untyped-lib'';

tsconfig.json の typeRoots / types 設定

typeRootstypes の設定が不適切だと、型定義ファイルが読み込まれず TS2304 が発生します。

tsconfig.json の設定例
{
  "compilerOptions": {
    // typeRoots: 型定義を探すディレクトリ
    // デフォルトは ["node_modules/@types"]
    "typeRoots": [
      "./node_modules/@types",
      "./src/types"  // カスタム型定義ディレクトリ
    ],

    // types: 読み込む型パッケージを限定する
    // 指定するとそれ以外は読み込まれない!
    "types": ["node", "jest"]
  }
}

注意:types を指定すると、指定したパッケージのみが自動読み込みされます。例えば "types": ["node"] と設定すると、@types/jest がインストールされていても読み込まれません。

ambient declaration(declare)の使い方

declare キーワードは、TypeScriptに「この識別子は実行時に存在する」と伝えるための宣言です。外部スクリプトで定義されたグローバル変数や、CDNで読み込んだライブラリの型を宣言する際に使います。

declare の各パターン
// グローバル変数の宣言
declare const gtag: Function;
declare const __DEV__: boolean;

// グローバル関数の宣言
declare function sendAnalytics(event: string, data: Record<string, unknown>): void;

// グローバルな Window インターフェースの拡張
declare global {
  interface Window {
    myApp: {
      version: string;
      init(): void;
    };
  }
}

// export {} が必要(ファイルをモジュールとして扱うため)
export {};

ポイント:declare global を使うファイルには、export {} を追加してモジュールとして認識させる必要があります。これがないと、ファイル全体がグローバルスクリプトとして扱われ、意図しない動作になる場合があります。

DOM API でのTS2304

ブラウザで実行するコードでは documentwindowHTMLElement などの DOM API を使いますが、TypeScriptの設定によってはこれらが認識されずTS2304が発生します。

document / window が見つからない

最も多いケースは、tsconfig.jsonlib"DOM" が含まれていない場合です。

error TS2304: Cannot find name ”document”.

NGの tsconfig.json
{
  "compilerOptions": {
    "lib": ["ES2020"]  // DOM が含まれていない!
  }
}
OKの tsconfig.json
{
  "compilerOptions": {
    "lib": ["ES2020", "DOM", "DOM.Iterable"]
  }
}

HTMLElement / Event 等のDOM型

HTMLElementHTMLInputElementEventMouseEvent などのDOM型も lib: ["DOM"] に依存します。

error TS2304: Cannot find name ”HTMLInputElement”.

NGコード
// lib に DOM がない場合
const input = document.querySelector("input") as HTMLInputElement;
// TS2304: Cannot find name ''HTMLInputElement''

function handleClick(e: MouseEvent) {
// TS2304: Cannot find name ''MouseEvent''
  console.log(e.clientX);
}

解決策:tsconfig.jsonlib"DOM" を追加します。前述の設定と同じです。

Node.js 環境で DOM を参照した場合

Node.js(サーバーサイド)のコードで documentwindow を使うと、lib"DOM" を追加していてもロジック的に間違いです。これは設計上の問題であり、DOM APIは使えません。

注意:Node.js環境の tsconfig.json では lib"DOM" を入れるべきではありません。DOM APIが使えてしまうと、サーバーサイドで実行時エラーになります。SSRやテスト環境でDOMが必要な場合は jsdom などのライブラリを使いましょう。

tsconfig.json の lib 設定の選び方

プロジェクトの実行環境に合わせて lib を設定しましょう。

環境 推奨 lib 設定
ブラウザ(フロントエンド) ["ES2020", "DOM", "DOM.Iterable"]
Node.js(サーバーサイド) ["ES2020"](DOM なし)
React(フロントエンド) ["ES2020", "DOM", "DOM.Iterable"]
Next.js(SSR + クライアント) ["ES2020", "DOM", "DOM.Iterable"]

Node.js 固有のTS2304

Node.js環境特有のグローバル変数やモジュールを使う際に発生するTS2304です。@types/node のインストールと正しい設定が鍵となります。

process / __dirname / __filename / Buffer / require

Node.jsのグローバル変数は、@types/node がインストールされていないとTS2304になります。

error TS2304: Cannot find name ”process”.

NGコード
// @types/node がインストールされていない
const port = process.env.PORT;  // TS2304: Cannot find name ''process''
const dir = __dirname;  // TS2304: Cannot find name ''__dirname''
const buf = Buffer.from("hello");  // TS2304: Cannot find name ''Buffer''
解決方法
# @types/node をインストール
npm install --save-dev @types/node
Node.js グローバル 用途 必要な型定義
process プロセス情報・環境変数 @types/node
__dirname 現在のディレクトリパス @types/node
__filename 現在のファイルパス @types/node
Buffer バイナリデータの操作 @types/node
require CommonJS モジュール読み込み @types/node
global / globalThis グローバルオブジェクト @types/node

ES Modules での __dirname / __filename

ES Modules("type": "module")では、__dirname__filename は使えません。代わりに import.meta.url を使います。

error TS2304: Cannot find name ”__dirname”.

NGコード(ESM環境)
// ES Modules では __dirname は使えない
const configPath = __dirname + "/config.json";  // TS2304
OKコード(ESM での代替)
import { fileURLToPath } from ''node:url'';
import { dirname, join } from ''node:path'';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const configPath = join(__dirname, "config.json");  // OK

global / globalThis の使い方

Node.jsのグローバルオブジェクトにカスタムプロパティを追加する場合は、型定義の拡張が必要です。

global の型拡張(global.d.ts)
declare global {
  var db: DatabaseConnection;
  var logger: Logger;
}

export {};
使用側のコード
// 型定義があるので TS2304 にならない
globalThis.db.query("SELECT * FROM users");
globalThis.logger.info("Server started");

注意:declare global 内で var を使う理由は、constlet はグローバルスコープに変数を追加できないためです。これは TypeScript の仕様です。

テストフレームワークでのTS2304

Jest や Vitest などのテストフレームワークが提供するグローバル関数(describeitexpect など)でTS2304が発生するケースです。テスト専用の型設定が必要です。

Jest: describe / it / expect / jest

Jestのテストファイルで describeexpect が見つからない場合、@types/jest のインストールと設定が必要です。

error TS2304: Cannot find name ”describe”.

NGコード(sum.test.ts)
// @types/jest がインストールされていない
describe("sum", () => {  // TS2304: Cannot find name ''describe''
  it("1 + 2 = 3", () => {  // TS2304: Cannot find name ''it''
    expect(sum(1, 2)).toBe(3);  // TS2304: Cannot find name ''expect''
  });
});
解決方法
# 1. @types/jest をインストール
npm install --save-dev @types/jest

# 2. tsconfig.json の types に jest を追加
# もしくは tsconfig.json で types を指定していなければ自動で読み込まれる
tsconfig.json の設定
{
  "compilerOptions": {
    "types": ["jest", "node"]
  },
  "include": ["src/**/*", "tests/**/*"]  // テストファイルも含める
}

Vitest: vi / describe / expect

Vitest は独自の型定義を持っています。@types/jest は不要で、代わりに Vitest の設定が必要です。

方法1: tsconfig.json で型を指定
{
  "compilerOptions": {
    "types": ["vitest/globals"]
  }
}
方法2: vitest.config.ts で globals を有効化
// vitest.config.ts
import { defineConfig } from ''vitest/config'';

export default defineConfig({
  test: {
    globals: true,  // describe, it, expect をグローバルに
  },
});

ポイント:Vitest では globals: true を設定しなくても、各テストファイルで import { describe, it, expect } from ''vitest'' と明示的にインポートする方法もあります。この方法なら型設定の問題を完全に回避できます。

tsconfig の include 設定の確認

テストファイルが tsconfig.jsoninclude に含まれていないと、型チェックの対象外となりTS2304が出ます。

テストファイルを include に含める
{
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "tests/**/*.ts",      // テストディレクトリを追加
    "**/*.test.ts",       // テストファイルパターン
    "**/*.spec.ts"        // specファイルパターン
  ]
}

React / JSX でのTS2304

React開発では、JSX構文やフックの使い方に関連するTS2304が発生することがあります。React 17以降のJSX Transformの変更も重要なポイントです。

React が見つからない(React 17+ の jsx transform)

React 17以前は、JSXを使うファイルに import React from ''react'' が必要でした。React 17以降の新しいJSX Transformでは不要になりましたが、tsconfig.jsonの設定が必要です。

error TS2304: Cannot find name ”React”.

NGコード(React 17+ で jsx: “react” を使用中)
// import React がない + jsx: "react" の場合
const App = () => {
  return <div>Hello</div>;  // TS2304: Cannot find name ''React''
};
OKコード 方法1: jsx を “react-jsx” に変更(推奨)
// tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx"  // React 17+ の新しい JSX Transform
  }
}
OKコード 方法2: import React を追加
import React from ''react'';  // 明示的にインポート

const App = () => {
  return <div>Hello</div>;  // OK
};
jsx 設定 import React 必要? React バージョン
"react" 必要 16以前
"react-jsx" 不要 17以降(推奨)
"react-jsxdev" 不要 17以降(開発用)

カスタムコンポーネント名の大文字/小文字

Reactでは、カスタムコンポーネントは大文字で始める必要があります。小文字で始まるとHTML要素として解釈されます。

NGコード
// 小文字で始まるコンポーネント名
const myButton = () => <button>Click</button>;

// JSXで使うと HTML 要素として解釈される
const App = () => <myButton />;  // HTML にそんな要素はない
OKコード(修正例)
// 大文字で始めるのが React のルール
const MyButton = () => <button>Click</button>;

const App = () => <MyButton />;  // OK

useState / useEffect の import 忘れ

Reactのフック関数は react パッケージからインポートする必要があります。

error TS2304: Cannot find name ”useState”.

NGコード
// import を忘れている
const Counter = () => {
  const [count, setCount] = useState(0);  // TS2304: Cannot find name ''useState''

  useEffect(() => {  // TS2304: Cannot find name ''useEffect''
    document.title = `Count: ${count}`;
  }, [count]);

  return <button onClick={() => setCount(count + 1)}>{count}</button>;
};
OKコード(修正例)
import { useState, useEffect } from ''react'';

const Counter = () => {
  const [count, setCount] = useState(0);  // OK
  useEffect(() => {  // OK
    document.title = `Count: ${count}`;
  }, [count]);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
};

グローバル変数・環境変数でのTS2304

ブラウザのグローバル変数(window.XXX)や環境変数(process.env.XXX)に型がないとTS2304が発生します。型定義の拡張で対処します。

window にカスタムプロパティを追加する場合

CDNで読み込んだライブラリや、HTMLのscriptタグで定義したグローバル変数を TypeScript で使う場合、Window インターフェースの拡張が必要です。

error TS2304: Cannot find name ”gtag”.

NGコード
// Google Analytics の gtag をそのまま使おうとしている
gtag("event", "click", {
  event_category: "button",
});  // TS2304: Cannot find name ''gtag''
OKコード(src/types/global.d.ts)
// Google Analytics の型定義
declare function gtag(
  command: "config" | "event" | "set",
  targetId: string,
  config?: Record<string, unknown>
): void;

// Window にカスタムプロパティを追加
declare global {
  interface Window {
    dataLayer: Record<string, unknown>[];
  }
}
export {};

process.env の型定義

環境変数は process.env.XXX の形でアクセスしますが、デフォルトでは string | undefined 型です。カスタムの環境変数に型を付けるには、NodeJS.ProcessEnv を拡張します。

src/types/env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    NODE_ENV: "development" | "production" | "test";
    PORT?: string;
    DATABASE_URL: string;
    API_KEY: string;
  }
}

Vite の環境変数(import.meta.env)

Viteでは process.env ではなく import.meta.env を使います。カスタム環境変数の型は ImportMetaEnv を拡張して定義します。

error TS2304: Cannot find name ”ImportMetaEnv”.

src/vite-env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string;
  readonly VITE_APP_TITLE: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

ポイント:Viteの環境変数は VITE_ プレフィックスが付いたものだけがクライアントサイドに公開されます。VITE_ のない環境変数はサーバーサイドのみで利用可能です。

tsconfig.json の設定で解決するTS2304

tsconfig.json の設定が原因でTS2304が発生するケースを体系的にまとめます。設定一つで多くのエラーが解消されることがあります。

lib オプション

lib は、TypeScriptが認識するビルトインAPIの範囲を指定します。

lib 値 提供される API 解消される TS2304
ES2015 Promise, Map, Set, Symbol Promise, Map, Set
ES2017 Object.entries/values, SharedArrayBuffer SharedArrayBuffer
ES2020 BigInt, Promise.allSettled, globalThis BigInt, globalThis
ES2021 Promise.any, WeakRef, FinalizationRegistry WeakRef
DOM document, window, HTMLElement, Event document, window, HTMLElement
DOM.Iterable NodeList.forEach, HTMLCollection の反復処理 NodeList の for…of

include / exclude の設定ミス

include パターンにファイルが含まれていないと、そのファイルは型チェックの対象外となりTS2304が出ます。

よくあるNG設定
{
  "include": ["src/**/*.ts"],  // .tsx が含まれていない!
  "exclude": ["**/*.test.ts"]  // テストファイルが除外されている
}
OK設定
{
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "tests/**/*.ts",
    "src/types/**/*.d.ts"
  ]
}

moduleResolution の選択

moduleResolution はモジュールの解決戦略を指定します。設定によってインポートの挙動が大きく変わります。

moduleResolution 特徴 推奨環境
"node" Node.js の CommonJS 解決方式 レガシープロジェクト
"node16" / "nodenext" ESM + CJS のハイブリッド解決 Node.js(モダン)
"bundler" バンドラー準拠(拡張子省略可) Vite / webpack / esbuild

baseUrl / paths の設定

baseUrlpaths を使ったパスエイリアスの設定例です。

tsconfig.json のパスエイリアス設定
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@components/*": ["src/components/*"],
      "@utils/*": ["src/utils/*"],
      "@types/*": ["src/types/*"]
    }
  }
}

注意:paths は TypeScript コンパイラの型解決にのみ影響します。実行時のモジュール解決には影響しません。Vite なら resolve.alias、webpack なら resolve.alias で同じパスマッピングを設定する必要があります。

tsconfig の設定チェックリスト

TS2304が発生したときの tsconfig.json チェックリストです。

tsconfig.json チェックリスト

  • lib に必要なライブラリ(DOM, ES2020 等)が含まれているか?
  • types を指定している場合、必要な型パッケージが全て列挙されているか?
  • typeRoots にカスタム型定義ディレクトリが含まれているか?
  • include にソースファイルとテストファイルが含まれているか?
  • exclude で必要なファイルを除外していないか?
  • moduleResolution がプロジェクトの実行環境に合っているか?
  • baseUrl / paths がビルドツール側の設定と一致しているか?

実務でよくあるTS2304パターン10選

ここまでの内容を踏まえた上で、実際の開発現場でよく遭遇するTS2304パターンをランキング形式でまとめます。

パターン1: ライブラリの型定義が不足している

JavaScriptライブラリを使う際に @types/xxx のインストールを忘れるケースです。

よくある例と解決コマンド
# Express
npm install --save-dev @types/express

# Lodash
npm install --save-dev @types/lodash

# cors
npm install --save-dev @types/cors

パターン2: グローバル変数(jQuery の $ 、Google Analytics の gtag)

CDNで読み込んだライブラリのグローバル変数です。declare 文か @types パッケージで型を定義します。

declare での最小限の型定義
// jQuery
declare const $: any;
declare const jQuery: any;

// Google Analytics
declare function gtag(...args: any[]): void;

パターン3: Jest / Vitest のテスト関数

describeitexpectjestvi が見つからないケースです。@types/jest または vitest/globals の設定が必要です。

パターン4: Node.js の process / __dirname

@types/node のインストール忘れ、またはES Modulesでの __dirname 使用です。

パターン5: React の useState / useEffect の import 忘れ

Reactフックのインポートを忘れるパターンです。VS Code の Quick Fix で自動追加しましょう。

パターン6: tsconfig.json の lib に DOM がない

フロントエンドプロジェクトで documentwindow が使えないケースです。lib: ["DOM"] を追加します。

パターン7: モジュールの拡張子問題

moduleResolution: "nodenext" で拡張子が必要なのに省略しているケースです。.js 拡張子を付けるか、moduleResolution: "bundler" に切り替えます。

パターン8: monorepo でのパッケージ参照

monorepo構成で他パッケージの型が解決できないケースです。references を使った Project References や、パッケージの types フィールド設定が必要です。

monorepo での tsconfig 設定例
// packages/app/tsconfig.json
{
  "compilerOptions": {
    "composite": true
  },
  "references": [
    { "path": "../shared" }
  ]
}

パターン9: CI/CD 環境での型エラー

ローカルでは動くのにCI/CDで TS2304 が出るケースです。主な原因は以下の通りです。

原因 対策
@types/* が devDependencies にしかない CI で npm ci を使い devDependencies も含めてインストール
Node.js のバージョン違い .nvmrc / .node-version でバージョンを統一
キャッシュの問題 node_modules を削除して再インストール

パターン10: const enum を isolatedModules で使う

isolatedModules: true(Vite / esbuild のデフォルト)の環境で、別ファイルの const enum を参照するとTS2304が発生することがあります。

解決策: const enum を通常の enum に変更
// NG: const enum は isolatedModules でインライン化できない
export const enum Direction { Up, Down, Left, Right }

// OK: 通常の enum を使う
export enum Direction { Up, Down, Left, Right }

// さらに良い: as const オブジェクトを使う
export const Direction = {
  Up: 0,
  Down: 1,
  Left: 2,
  Right: 3,
} as const;
type Direction = (typeof Direction)[keyof typeof Direction];

まとめ

TS2304(Cannot find name)は、TypeScript開発で非常に頻繁に遭遇するエラーです。この記事で解説したパターンを最後に振り返りましょう。

TS2304 の解決フローチャート

  • 1. タイポ・スペルミスはないか? → エディタの補完機能を活用
  • 2. import 文を書き忘れていないか? → VS Code の Quick Fix (Ctrl + .)
  • 3. @types パッケージはインストールされているか?npm install -D @types/xxx
  • 4. tsconfig.json の lib は正しいか? → DOM / ES2020 等を確認
  • 5. tsconfig.json の types は正しいか? → 指定している場合、全ての型を列挙
  • 6. tsconfig.json の include にファイルが含まれているか? → .tsx やテストファイルも含める
  • 7. declare 文やカスタム型定義ファイルが必要か? → .d.ts を作成

TS2304 と関連エラーの違いまとめ

エラー メッセージ 主な原因 主な解決策
TS2304 Cannot find name 識別子が未宣言 import / declare / @types
TS2552 Cannot find name… Did you mean? タイポ 候補の名前に修正
TS2307 Cannot find module モジュールが見つからない npm install / パス修正
TS2322 Type is not assignable 型の不一致 型を一致させる
TS2339 Property does not exist 型にプロパティがない 型定義を修正 / 型アサーション
TS2345 Argument is not assignable 引数の型不一致 引数の型を修正

関連記事

TypeScriptの型システムやその他のエラーコードについてさらに深く学びたい方は、以下の記事もあわせてお読みください。

TypeScript 関連記事