エラーの内容
Object is possibly 'undefined'. ts(2532)
TypeScript が undefined になる可能性のある値を検出しました。チェックなしでその値を使おうとしています。コンパイラは意図的にこれをブロックします。実行時にその値が本当に undefined だった場合、アプリがクラッシュします。
よくあるトリガー:
- インデックスによる配列要素へのアクセス:
arr[0].name Mapの検索結果の読み取り:map.get(key).value- チェックなしで使用されるオプションの関数パラメータ
- DOM クエリ:
document.querySelector('#btn').addEventListener(...) T | undefinedとして型付けされたプロパティ
根本原因
厳格な null チェック(strictNullChecks: true)は、tsconfig.json で "strict": true を使用するとデフォルトで有効になります。このフラグが有効な場合、undefined は独自の型になります。TypeScript は T | undefined の値を常に T であるかのように扱うことを許可しません。
最小限の再現例:
const users: User[] = getUsers();
const first = users[0]; // 型: User | undefined
console.log(first.name); // ❌ Object is possibly 'undefined'. ts(2532)
配列インデックスアクセスが T | undefined を返すのは、インデックス 0 が存在しない可能性があるためです。たとえば、getUsers() が空の配列を返す場合などです。
修正方法 — 複数のアプローチ
1. オプショナルチェーン(?.)— 読み取りに最もシンプル
?. 演算子は短絡評価を行い、スローする代わりに undefined を返します。余分な変数は不要です。
console.log(first?.name); // ✅ first が undefined なら undefined を返す
// 必要なだけ深くチェーンできる
console.log(user?.address?.city);
// メソッド呼び出しにも使える
user?.save();
undefined の結果が許容される場合(値が欠けていると何も表示しない UI のレンダリングなど)は、まずこれを検討してください。
2. Null 合体演算子(??)— フォールバックを提供する
値が欠けている場合のデフォルトを提供するために、?? とオプショナルチェーンを組み合わせます:
const name = user?.name ?? 'Anonymous';
const count = map.get(key)?.total ?? 0;
3. 明示的な if チェック(型ガード)
値に対して複数行のロジックを実行する必要がある場合、ガードブロックの方が ?. をあちこちに散りばめるより整理されます。
const first = users[0];
if (first) {
console.log(first.name); // ✅ TypeScript はここで User に絞り込む
first.activate();
first.trackVisit();
}
// 関数では早期リターンが効果的
function greet(user: User | undefined) {
if (!user) return;
console.log(`Hello, ${user.name}`); // ✅ 安全
}
4. 非 null アサーション(!)— 慎重に使用する
! 演算子はコンパイラへの約束です:「この値は undefined ではない — 保証する」。TypeScript はそれを信頼してチェックをスキップします。実行時の安全性はゼロです。
const btn = document.querySelector('#submit')!;
btn.addEventListener('click', handleClick); // ✅ コンパイラは満足
// インラインバージョン
console.log(users[0]!.name);
これは本当に確実な状況(React コンポーネントの useEffect でレンダリングした直後の DOM 要素など)に限定してください。! を至る所に使うと、厳格な null チェックの意味が完全に失われます。
5. 配列インデックスアクセス — noUncheckedIndexedAccess を有効にする
このエラーが特に arr[i] で発生していますか?TypeScript 4.1 では、プロジェクト全体でこれを明示的にする noUncheckedIndexedAccess が追加されました:
// tsconfig.json
{
"compilerOptions": {
"noUncheckedIndexedAccess": true
}
}
これを有効にすると、arr[0] はどこでも T | undefined として型付けされます — 予期しない動作はありません。使用前にガードしてください:
const first = users[0];
if (first !== undefined) {
console.log(first.name); // ✅
}
6. Map.get() パターン
const cache = new Map();
// 修正前
const config = cache.get('main');
config.timeout = 5000; // ❌ possibly undefined
// 修正後 — ガード
const config = cache.get('main');
if (config) {
config.timeout = 5000; // ✅
}
// 修正後 — フォールバック
const config = cache.get('main') ?? defaultConfig;
config.timeout = 5000; // ✅
7. DOM クエリ
querySelector は undefined ではなく Element | null を返しますが、同じ修正が適用されます:
const btn = document.querySelector('#submit');
// オプション A: 非 null アサーション(要素の存在が確実な場合のみ)
btn!.addEventListener('click', handleClick);
// オプション B: ガード(DOM に存在しない可能性がある要素には安全)
if (btn) {
btn.addEventListener('click', handleClick);
}
非 null アサーションを使ってはいけない場合
実行時に本当にオプショナルな値があります。それらに ! を使うと、コンパイル時エラーが実行時クラッシュに変わり、より悪い結果になります。
- API レスポンス:古いサーバーバージョンやエラー状態ではフィールドが欠けている場合がある
- ユーザー入力とフォームの値
- ファイルや環境変数から読み込まれた設定
- 厳格な型付けのないサードパーティライブラリからのデータ
これらすべてに対して、実際のガードを記述するかフォールバックを提供してください。
確認方法
TypeScript コンパイラを直接実行して、エラーが残っていないことを確認します:
# プロジェクト全体をチェック
npx tsc --noEmit
# 単一ファイルをチェック
npx tsc --noEmit src/utils.ts
VS Code では、保存するとすぐに赤い波線が消えます。変数にホバーしてください — TypeScript が User | undefined から User に絞り込んでいれば、修正が機能しています。
予防策
tsconfig.jsonで"strict": trueを維持してください。このエラーを黙らせるためにstrictNullChecksを無効にするのは修正ではありません- 外部データソースからネストされたプロパティを読み取る際は、デフォルトで
?.を使用してください - DOM クエリには型付きジェネリクスを使用してください:
querySelector<HTMLInputElement> - 関数に明示的な戻り値の型を追加してください — 何かが
undefinedを返す可能性があることが明確になります - Zod のようなスキーマライブラリでエントリポイントで API レスポンスを検証し、内部型が常に完全に定義されるようにしてください

