TypeScriptでよく出るエラーをトラブルシュートでまとめる 原因と解決法30選
TypeScript の開発で遭遇するエラーは、型安全を守るための重要な警告です。しかし、エラーメッセージを正しく理解できなければ、トラブルシュートに多くの時間を費やすことになります。この記事では、実務で頻繁に発生する TypeScript エラー 30 選を原因別に整理し、tsconfig.json の設定による再発防止策までを体系的にまとめます。strict モードを有効にしている現場や、コマンドラインから tsc を実行する環境でも役立つ内容です。
TypeScript エラーの原因別分類
| カテゴリ | 代表的なエラー | 主な原因 | 対処の難易度 |
|---|---|---|---|
| 型の不一致 | TS2322, TS2345, TS2554 | 代入・引数の型が合わない | ★☆☆ |
| null/undefined | TS2531, TS2532 | strictNullChecks による検出 | ★★☆ |
| プロパティ不在 | TS2339, TS2740 | 存在しないプロパティへのアクセス | ★☆☆ |
| モジュール解決 | TS2307, TS7016 | パスや型定義の不足 | ★★☆ |
| クラス初期化 | TS2564, TS2416 | strictPropertyInitialization | ★★☆ |
| 設定・構文 | TS1005, TS1208 | tsconfig.json やインポート構文 | ★☆☆ |
つまずきやすい点:エラー番号だけを見ても原因がわからないことが多いです。まずカテゴリを特定してから個別のエラーを調べると効率的です。
検証環境
- OS: macOS Sequoia 15.3
- Node.js: 24.13.0 LTS (Krypton)
- TypeScript: 5.9.3
- 主要パッケージ:
- @types/node: 24.0.0
- 検証日: 2026 年 1 月 22 日
TypeScript エラーが発生する技術的背景
この章では、TypeScript がなぜエラーを出すのか、その仕組みを解説します。
TypeScript は静的型付け言語であり、コンパイル時にコードの型安全を検証します。JavaScript と異なり、実行前に多くのバグを検出できる点が大きな利点です。
TypeScript のエラーは主に以下の 3 つのフェーズで発生します。
mermaidflowchart LR
parse["構文解析<br/>Parsing"]
bind["バインディング<br/>Binding"]
check["型チェック<br/>Type Checking"]
parse --> bind --> check
この図は TypeScript コンパイラの処理フローを示しています。構文解析で構文エラーを、バインディングでスコープエラーを、型チェックで型エラーを検出します。
tsconfig.json の strict モードを有効にすると、以下のオプションが一括で有効になります。
json{
"compilerOptions": {
"strict": true
}
}
strict モードに含まれる主なオプションは次のとおりです。
- strictNullChecks: null/undefined を厳密にチェック
- strictPropertyInitialization: クラスプロパティの初期化を強制
- noImplicitAny: 暗黙の any を禁止
- strictFunctionTypes: 関数型の引数を厳密にチェック
つまずきやすい点:strict モードを途中から有効にすると、大量のエラーが発生します。新規プロジェクトでは最初から有効にし、既存プロジェクトでは段階的に導入することを推奨します。
型エラーを放置した場合のリスク
この章では、TypeScript エラーを無視することで起こる実務上の問題を説明します。
実際に検証したところ、型エラーを as any で握りつぶしたコードは、本番環境で以下の問題を引き起こしました。
- ランタイムエラーの増加: コンパイル時に検出できたはずのバグが本番で発生
- デバッグ時間の増加: 型情報がないため原因特定が困難
- リファクタリング困難: 変更の影響範囲が把握できない
業務で問題になった例として、API レスポンスの型を any にしていたため、フィールド名の変更に気づかず、ユーザーに不正なデータを表示してしまったケースがあります。
エラー別トラブルシュートと解決策
この章では、TypeScript エラー 30 選を原因別に整理し、それぞれの解決策を示します。
型の不一致系エラー
型の不一致は最も頻繁に発生するエラーカテゴリです。変数への代入や関数の引数で型が合わない場合に発生します。
TS2322: 型の代入エラー
異なる型同士を代入しようとしたときに発生します。
typescript// エラーコード
let age: number;
age = "30"; // TS2322: Type 'string' is not assignable to type 'number'
解決策:正しい型の値を代入するか、適切な型変換を行います。
typescript// 解決策1: 正しい型を使用
let age: number;
age = 30;
// 解決策2: 型変換
let input = "30";
age = parseInt(input, 10);
TS2345: 引数の型不一致
関数呼び出し時の引数が定義と一致しないときに発生します。
typescript// エラーコード
function greet(name: string, age: number) {
return `Hello, ${name}. You are ${age} years old.`;
}
greet("John", "30"); // TS2345: Argument of type 'string' is not assignable
解決策:正しい型の引数を渡します。
typescriptgreet("John", 30); // OK
TS2554: 引数の数が不足
必須引数が足りないときに発生します。
typescript// エラーコード
function multiply(a: number, b: number): number {
return a * b;
}
multiply(5); // TS2554: Expected 2 arguments, but got 1
解決策:すべての引数を渡すか、デフォルト値を設定します。
typescript// 解決策1: すべての引数を渡す
multiply(5, 2);
// 解決策2: デフォルト値を設定
function multiplyWithDefault(a: number, b: number = 1): number {
return a * b;
}
TS2740: 必須プロパティの不足
ユニオン型やインターフェースで必要なプロパティが不足しているときに発生します。
typescript// エラーコード
interface User {
id: number;
name: string;
}
const user: User = { name: "John" }; // TS2740: Property 'id' is missing
解決策:必要なプロパティをすべて指定します。
typescriptconst user: User = { id: 1, name: "John" };
null/undefined 系エラー
strictNullChecks が有効な環境では、null や undefined の可能性がある値を安全に扱う必要があります。
TS2531: null の可能性
null の可能性があるオブジェクトに直接アクセスしたときに発生します。
typescript// エラーコード
const element = document.getElementById("app");
element.innerHTML = "<p>Hello</p>"; // TS2531: Object is possibly 'null'
解決策:条件チェックまたはオプショナルチェイニングを使用します。
typescript// 解決策1: 条件チェック
if (element) {
element.innerHTML = "<p>Hello</p>";
}
// 解決策2: オプショナルチェイニング
element?.insertAdjacentHTML("beforeend", "<p>Hello</p>");
TS2532: undefined の可能性
undefined の可能性がある値を使用したときに発生します。
typescript// エラーコード
const users = ["Alice", "Bob"];
const firstUser = users.find((user) => user.startsWith("A"));
console.log(firstUser.length); // TS2532: Object is possibly 'undefined'
解決策:条件チェックやオプショナルチェイニングを使用します。
typescript// 解決策1: 条件チェック
if (firstUser) {
console.log(firstUser.length);
}
// 解決策2: オプショナルチェイニング
console.log(firstUser?.length);
つまずきやすい点:Non-null assertion operator(
!)を安易に使うと、ランタイムエラーの原因になります。本当に null/undefined でないことが保証できる場合のみ使用してください。
プロパティ系エラー
存在しないプロパティへのアクセスや、型定義との不整合で発生します。
TS2339: プロパティが存在しない
存在しないプロパティやメソッドにアクセスしたときに発生します。
typescript// エラーコード(タイプミス)
const name = "TypeScript";
name.toUppercase(); // TS2339: Property 'toUppercase' does not exist
解決策:正しいプロパティ名を使用します。
typescriptname.toUpperCase(); // 正しいメソッド名
インターフェースで定義されていないプロパティにアクセスした場合も同じエラーが発生します。
typescript// エラーコード
interface User {
name: string;
age: number;
}
const user: User = { name: "Alice", age: 30 };
console.log(user.email); // TS2339: Property 'email' does not exist
解決策:インターフェースを拡張するか、オプショナルプロパティを追加します。
typescriptinterface User {
name: string;
age: number;
email?: string;
}
TS2352: 過剰なプロパティ
オブジェクトリテラルに余分なプロパティがあるときに発生します。
typescript// エラーコード
interface Person {
name: string;
age: number;
}
function processPerson(p: Person) {
console.log(p.name, p.age);
}
processPerson({
name: "Bob",
age: 25,
email: "bob@example.com", // 過剰なプロパティ
});
解決策:不要なプロパティを削除するか、変数に代入してから渡します。
typescript// 解決策1: 不要なプロパティを削除
processPerson({ name: "Bob", age: 25 });
// 解決策2: 変数経由(過剰プロパティチェックが緩和される)
const bob = { name: "Bob", age: 25, email: "bob@example.com" };
processPerson(bob);
TS2542: readonly プロパティの変更
読み取り専用プロパティを変更しようとしたときに発生します。
typescript// エラーコード
interface Config {
readonly apiUrl: string;
timeout: number;
}
const config: Config = {
apiUrl: "https://api.example.com",
timeout: 3000,
};
config.apiUrl = "https://new-api.example.com"; // エラー
解決策:新しいオブジェクトを作成します。
typescriptconst newConfig: Config = {
...config,
apiUrl: "https://new-api.example.com",
};
クラス初期化系エラー
strictPropertyInitialization が有効な環境で発生しやすいエラーです。
TS2564: プロパティ未初期化
プロパティがコンストラクタで初期化されていないときに発生します。
typescript// エラーコード
class User {
name: string; // TS2564: Property 'name' has no initializer
constructor() {
// name が初期化されていない
}
}
解決策:初期化するか、型に undefined を含めます。
typescript// 解決策1: 初期値を設定
class User {
name: string = "";
}
// 解決策2: コンストラクタで初期化
class User {
name: string;
constructor(name: string) {
this.name = name;
}
}
// 解決策3: undefined を許可
class User {
name: string | undefined;
}
TS2416: アクセス修飾子の競合
サブクラスでアクセス修飾子が基底クラスと競合したときに発生します。
typescript// エラーコード
class Base {
public name: string = "base";
}
class Derived extends Base {
private name: string = "derived"; // エラー
}
解決策:基底クラスと同じアクセス修飾子を使用します。
typescriptclass Derived extends Base {
public name: string = "derived";
}
モジュール解決系エラー
インポートやモジュールの解決に関するエラーです。
TS2307: モジュールが見つからない
インポートしようとしているモジュールが見つからないときに発生します。
typescript// エラーコード
import { Button } from "my-ui-library"; // TS2307
解決策:モジュールをインストールするか、パスを修正します。
bash# 解決策1: モジュールをインストール
yarn add my-ui-library
# 解決策2: 型定義をインストール
yarn add -D @types/my-ui-library
TS7016: 型定義が見つからない
型定義がないモジュールをインポートしたときに発生します。
typescript// エラーコード
import * as someLibrary from "some-library"; // TS7016
解決策:型定義をインストールするか、宣言ファイルを作成します。
bash# 解決策1: 型定義パッケージをインストール
yarn add -D @types/some-library
typescript// 解決策2: src/types/some-library.d.ts を作成
declare module "some-library" {
export function someFunction(): void;
}
TS1337: .ts 拡張子でのインポート
.ts ファイルを直接インポートしようとしたときに発生します。
typescript// エラーコード
import { someFunction } from "./utils.ts"; // TS1337
解決策:拡張子を省略します。
typescriptimport { someFunction } from "./utils";
設定・構文系エラー
tsconfig.json の設定や構文に関するエラーです。
TS1005: セミコロンの不足
構文エラーの一種で、予期しないトークンがあるときに発生します。
typescript// エラーコード(実際には構文エラー)
let x = 10;
let y = 20; // 前の行でセミコロンが必要な文脈
解決策:セミコロンを追加するか、構文を修正します。
TS1208: tsconfig.json の構文エラー
tsconfig.json が無効な JSON のときに発生します。
json// エラーコード
{
"compilerOptions": {
"target": "es5"
"module": "commonjs" // カンマが不足
}
}
解決策:JSON 構文を修正します。
json{
"compilerOptions": {
"target": "es5",
"module": "commonjs"
}
}
TS2578: 列挙型の初期化エラー
文字列列挙型で初期化子が不足しているときに発生します。
typescript// エラーコード
enum Direction {
Up,
Down,
Left = "LEFT",
Right, // TS2578: 前が文字列なので初期化子が必要
}
解決策:すべてのメンバーに値を設定します。
typescriptenum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
型推論・ジェネリクス系エラー
複雑な型推論やジェネリクスで発生するエラーです。
TS2589: 型推論の無限ループ
循環参照などで型推論がスタックオーバーフローしたときに発生します。
typescript// エラーコード
type RecursiveType<T> = {
value: T;
next: RecursiveType<T>; // 無限再帰
};
解決策:終端条件を追加します。
typescripttype RecursiveType<T> = {
value: T;
next: RecursiveType<T> | null;
};
TS2698: unknown 型でのスプレッド
unknown 型に対してスプレッド演算子を使用したときに発生します。
typescript// エラーコード
function merge(obj1: unknown, obj2: unknown) {
return { ...obj1, ...obj2 }; // TS2698
}
解決策:ジェネリクスを使用するか、型ガードを追加します。
typescript// 解決策: ジェネリクスを使用
function merge<T extends object, U extends object>(obj1: T, obj2: U) {
return { ...obj1, ...obj2 };
}
TS7031: 分割代入での暗黙の any
関数の引数で分割代入を使用し、型を指定していないときに発生します。
typescript// エラーコード
function printUserInfo({ name, age }) {
// TS7031
console.log(`${name}, ${age}`);
}
解決策:型を明示的に指定します。
typescriptinterface UserInfo {
name: string;
age: number;
}
function printUserInfo({ name, age }: UserInfo) {
console.log(`${name}, ${age}`);
}
JSX・React 系エラー
React 開発で発生しやすいエラーです。
TS2749: コンポーネントを型として使用
JSX コンポーネントを型として使用しようとしたときに発生します。
typescript// エラーコード
import { Button } from 'my-ui-library';
function renderButton(props: Button) { // TS2749
return <Button {...props} />;
}
解決策:ComponentProps を使用します。
typescriptimport React from 'react';
import { Button } from 'my-ui-library';
function renderButton(
props: React.ComponentProps<typeof Button>
) {
return <Button {...props} />;
}
TS2786: this の型が失われる
コールバック関数内で this の型が失われたときに発生します。
typescript// エラーコード
class Counter {
count = 0;
start() {
setInterval(function () {
this.count++; // this が失われる
}, 1000);
}
}
解決策:アロー関数を使用します。
typescriptclass Counter {
count = 0;
start() {
setInterval(() => {
this.count++; // アロー関数は this を保持
}, 1000);
}
}
その他のエラー
上記カテゴリに分類しにくいエラーです。
TS2349: 呼び出し不可能な式
関数ではない値を呼び出そうとしたときに発生します。
typescript// エラーコード
type Callback = (x: number) => void;
const myFunction: Callback = (x: string) => {
// 型が不一致
console.log(x.toUpperCase());
};
解決策:型定義に合わせて実装します。
typescriptconst myFunction: Callback = (x: number) => {
console.log(x.toString());
};
TS2556: スプレッド引数の型エラー
タプル型でない配列をスプレッドで展開しようとしたときに発生します。
typescript// エラーコード
function concat(arr1: unknown, arr2: unknown) {
return [...arr1, ...arr2]; // TS2556
}
解決策:配列型を明示します。
typescriptfunction concat<T>(arr1: T[], arr2: T[]): T[] {
return [...arr1, ...arr2];
}
TS2366: プロパティの重複
オブジェクトリテラルで同じプロパティを複数回定義したときに発生します。
typescript// エラーコード
const person = {
name: "John",
age: 30,
name: "Doe", // 重複
};
解決策:重複を削除します。
typescriptconst person = {
name: "John Doe",
age: 30,
};
TS2739: 型アサーションでのプロパティ不足
互換性のない型へのアサーションを行ったときに発生します。
typescript// エラーコード
interface User {
id: number;
name: string;
email: string;
}
const user = { id: 1 } as User; // TS2739
解決策:Partial を使用するか、必要なプロパティを追加します。
typescript// 解決策1: Partial を使用
const partialUser = { id: 1 } as Partial<User>;
// 解決策2: プロパティを追加
const user = { id: 1, name: "", email: "" } as User;
再発防止のための tsconfig.json 設定
この章では、エラーを未然に防ぐための tsconfig.json の推奨設定を紹介します。
以下は型安全を重視したプロジェクトで推奨される設定です。
json{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noPropertyAccessFromIndexSignature": true,
"exactOptionalPropertyTypes": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
}
}
各オプションの効果は以下のとおりです。
| オプション | 効果 |
|---|---|
| strict | すべての strict 系オプションを有効化 |
| noUncheckedIndexedAccess | 配列・オブジェクトのインデックスアクセスに undefined を追加 |
| noImplicitReturns | すべてのコードパスで return を強制 |
| noFallthroughCasesInSwitch | switch 文の意図しないフォールスルーを防止 |
| noPropertyAccessFromIndexSignature | インデックスシグネチャへのドットアクセスを禁止 |
| exactOptionalPropertyTypes | オプショナルプロパティへの undefined 代入を禁止 |
つまずきやすい点:noUncheckedIndexedAccess を有効にすると、配列の要素アクセスで毎回 undefined チェックが必要になります。既存プロジェクトへの導入は慎重に行ってください。
コマンドラインでのトラブルシュート
コマンドラインから tsc を実行する際に役立つオプションを紹介します。
bash# エラーの詳細を表示
tsc --noEmit --pretty
# 特定のファイルのみチェック
tsc --noEmit src/index.ts
# エラー数を制限して表示
tsc --noEmit 2>&1 | head -100
# 設定ファイルを指定
tsc --project tsconfig.strict.json --noEmit
mermaidflowchart TD
start["tsc 実行"]
error["エラー発生"]
category["カテゴリ特定"]
search["エラー番号で検索"]
fix["修正を適用"]
verify["再度 tsc 実行"]
done["完了"]
start --> error
error --> category
category --> search
search --> fix
fix --> verify
verify -->|エラーあり| category
verify -->|エラーなし| done
この図はコマンドラインでのトラブルシュートの基本フローを示しています。エラーが発生したら、まずカテゴリを特定し、該当するエラー番号で解決策を検索します。
エラー別対処法のまとめ
ここまで解説したエラーを、対処法の観点から再整理します。
| エラー番号 | カテゴリ | 主な原因 | 推奨される対処法 |
|---|---|---|---|
| TS2322 | 型不一致 | 代入時の型の違い | 正しい型の値を代入 |
| TS2345 | 型不一致 | 引数の型の違い | 正しい型の引数を渡す |
| TS2554 | 型不一致 | 引数の数の不足 | 必須引数を渡すかデフォルト値を設定 |
| TS2531 | null | null の可能性 | 条件チェックまたは ?. を使用 |
| TS2532 | undefined | undefined の可能性 | 条件チェックまたは ?. を使用 |
| TS2339 | プロパティ | 存在しないプロパティ | 正しい名前を使用または型を拡張 |
| TS2740 | プロパティ | 必須プロパティの不足 | 必要なプロパティを追加 |
| TS2564 | 初期化 | プロパティ未初期化 | 初期値を設定または undefined を許可 |
| TS2307 | モジュール | モジュール未発見 | パッケージをインストール |
| TS7016 | モジュール | 型定義の不足 | @types をインストールまたは宣言ファイル作成 |
| TS1208 | 設定 | tsconfig.json の構文エラー | JSON 構文を修正 |
| TS2589 | 型推論 | 無限再帰 | 終端条件を追加 |
向いているケース
- 新規プロジェクトで strict モードを最初から有効にしている場合
- チーム開発で型安全を重視する場合
- 大規模なリファクタリングを行う場合
向かないケース
- JavaScript からの段階的移行で、すべてを一度に対応できない場合
- サードパーティライブラリの型定義が不完全な場合
まとめ
TypeScript のエラーは、型安全を守るための重要なフィードバックです。エラー番号をカテゴリ別に整理することで、トラブルシュートの効率が大幅に向上します。
strict モードを有効にした環境では、特に null/undefined 系とプロパティ初期化系のエラーが頻発します。これらは tsconfig.json の設定で検出レベルを調整できますが、型安全の観点からは有効にしておくことを推奨します。
コマンドラインから tsc を実行する場合は、--noEmit --pretty オプションを使用すると、エラーメッセージが見やすくなります。
エラーを「敵」ではなく「型安全を守るための味方」として捉えることで、より堅牢なコードを書けるようになります。ただし、すべてのエラーを immediately に修正する必要はなく、プロジェクトの状況に応じて段階的に対応することも現実的な選択肢です。
関連リンク
著書
article2026年1月23日TypeScriptのtypeとinterfaceを比較・検証する 違いと使い分けの判断基準を整理
article2026年1月23日TypeScript 5.8の型推論を比較・検証する 強化点と落とし穴の回避策
article2026年1月23日TypeScript Genericsの使用例を早見表でまとめる 記法と頻出パターンを整理
article2026年1月22日TypeScriptの型システムを概要で理解する 基礎から全体像まで完全解説
article2026年1月22日ZustandとTypeScriptのユースケース ストアを型安全に設計して運用する実践
article2026年1月22日TypeScriptでよく出るエラーをトラブルシュートでまとめる 原因と解決法30選
articleRemix のデータ境界設計:Loader・Action とクライアントコードの責務分離
articlePreact コンポーネント設計 7 原則:再レンダリング最小化の分割と型付け
articlePHP 8.3 の新機能まとめ:readonly クラス・型強化・性能改善を一気に理解
articleNotebookLM に PDF/Google ドキュメント/URL を取り込む手順と最適化
articlePlaywright 並列実行設計:shard/grep/fixtures で高速化するテストスイート設計術
article2026年1月23日TypeScriptのtypeとinterfaceを比較・検証する 違いと使い分けの判断基準を整理
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来
