🫥
インデックスアクセス時にundefinedを考慮する
JavaScriptの特徴的な挙動の一つとして、配列やオブジェクトに存在しないインデックスやプロパティにアクセスするとundefined
が返される点があります。
この挙動は実行時エラーを引き起こす原因となるため注意が必要です。(自戒を込めて)
その問題を防ぐため、TypeScriptでは明示的にundefinedを考慮した安全なコードを書くことが推奨されます。
また、オブジェクトのプロパティアクセスでも同様の問題が発生する可能性があります。存在しないプロパティにアクセスした場合、その結果もundefinedとなります。
存在しないインデックスやプロパティにアクセスすると
以下の例では、存在しない配列のインデックスやオブジェクトのプロパティにアクセスした結果、エラーが発生します。
配列の場合
const arr: string[] = [];
const value = arr[0]; // value は undefined
const upperValue = value.toUpperCase(); // 実行時エラー: Cannot read properties of undefined
console.log(upperValue);
オブジェクトの場合
const obj: { [key: string]: string } = {};
const value = obj["nonExistentKey"]; // value は undefined
const upperValue = value.toUpperCase(); // 実行時エラー: Cannot read properties of undefined
console.log(upperValue);
解決策
noUncheckedIndexedAccess
オプションの有効化
1. tsconfig.json
にて、noUncheckedIndexedAccess
を有効にすることで、インデックスやキーでのアクセス時にundefined
を考慮した型を自動的に適用できます。
{
"compilerOptions": {
"noUncheckedIndexedAccess": true
}
}
このオプションを有効にすると、以下のように型が強化されます。
- 配列のインデックスアクセス:
T | undefined
- オブジェクトのプロパティアクセス:
T | undefined
これにより、undefined
を考慮しないコードはコンパイル時にエラーとして検出されます。
2. 安全なアクセス方法
以下はnoUncheckedIndexedAccess
有効時の安全なコード例です。
配列の場合
const arr: string[] = [];
const value = arr[0]; // 型は string | undefined
// オプショナルチェーンを使った安全なアクセス
const upperValue = value?.toUpperCase();
console.log(upperValue); // undefined
オブジェクトの場合
const obj: { [key: string]: string } = {};
const value = obj["nonExistentKey"]; // 型は string | undefined
// オプショナルチェーンを使った安全なアクセス
const upperValue = value?.toUpperCase();
console.log(upperValue); // undefined
undefined
の特定処理
3. undefined
のケースを明示的に処理したい場合、if
文やデフォルト値を活用できます。
if
文での処理
if (value === undefined) {
console.log("値が存在しません");
} else {
console.log(value.toUpperCase());
}
デフォルト値の設定
const upperValue = (value ?? "default").toUpperCase();
console.log(upperValue); // default
まとめ
TypeScriptのnoUncheckedIndexedAccess
オプションを有効にすると、潜在的なエラーを未然に防ぐことができます。また、undefined
を安全に処理するための機能(オプショナルチェーンや??
)を活用することで、実行時エラーを回避し、信頼性の高いコードを書くことが可能です。
途中から導入すると大変な時もある😺かも
Discussion