メインコンテンツまでスキップ

配列要素へのアクセス

JavaScriptでの配列要素アクセス#

JavaScriptの配列の要素にアクセスするにはブラケット[]を使います。ブラケットにはアクセスする要素のインデックス番号を書きます。インデックス番号は0始まりです。たとえば、abc = ["a", "b", "c"]の1つ目の要素にアクセスするには、abc[0]と書きます。

javascript
const abc = ["a", "b", "c"];
console.log(abc[0]); //=> "a"
javascript
const abc = ["a", "b", "c"];
console.log(abc[0]); //=> "a"

JavaScriptの配列では、存在しないインデックス番号でもアクセスできます。その場合でも、JavaScriptではエラーになりません。得られる値はundefinedになります。

javascript
const abc = ["a", "b", "c"];
console.log(abc[100]); //=> undefined
javascript
const abc = ["a", "b", "c"];
console.log(abc[100]); //=> undefined

TypeScriptの要素の型#

TypeScriptでは、Type[]型の配列から要素を取り出したとき、その値の型はTypeになります。たとえば、string[]型から0番目の要素の型はstringになります。

typescript
const abc: string[] = ["a", "b", "c"];
const character: string = abc[0];
typescript
const abc: string[] = ["a", "b", "c"];
const character: string = abc[0];

JavaScriptでは存在しないインデックスで要素アクセスした場合、エラーにならず、代わりにundefinedが得られると説明しましたが、TypeScriptでも不在要素へのアクセスについて、コンパイラーが警告することはありません。

typescript
const abc = ["a", "b", "c"];
const character: string = abc[100]; // エラーにはならない
typescript
const abc = ["a", "b", "c"];
const character: string = abc[100]; // エラーにはならない

要素アクセスで得た値はstringundefinedどちらの可能性もありながら、TypeScriptは常にstring型であると考えるようになっています。そのため、要素アクセスでundefinedが返ってくる場合のエラーはTypeScriptでは発見できず、JavaScript実行時に判明することになります。

typescript
const abc = ["a", "b", "c"];
const character: string = abc[100];
console.log(character); //=> undefined
character.toUpperCase();
// JavaScript実行時エラー: Cannot read properties of undefined (reading 'toUpperCase')
typescript
const abc = ["a", "b", "c"];
const character: string = abc[100];
console.log(character); //=> undefined
character.toUpperCase();
// JavaScript実行時エラー: Cannot read properties of undefined (reading 'toUpperCase')

TypeScriptで要素アクセスを型安全にする設定#

TypeScriptにこの問題を指摘してもらうようにするには、コンパイラーオプションのnoUncheckedIndexedAccessを有効にします。

これを有効にすると、たとえば、string[]配列から要素アクセスで得た値の型は、string型もしくはundefined型を意味するstring | undefinedになります。

typescript
const abc: string[] = ["a", "b", "c"];
const character: string | undefined = abc[0];
character.toUpperCase();
// コンパイルエラー: Object is possibly 'undefined'.(2532)
typescript
const abc: string[] = ["a", "b", "c"];
const character: string | undefined = abc[0];
character.toUpperCase();
// コンパイルエラー: Object is possibly 'undefined'.(2532)

string | undefined型のままではtoUpperCaseなどの文字列型のメソッドは呼び出せません。そこで、if文で変数が文字列型だけになるように絞り込みます。すると、文字列型のメソッドを呼び出してもコンパイルエラーで指摘されることがなくなります。

typescript
const abc: string[] = ["a", "b", "c"];
const character = abc[0];
// 絞り込み条件
if (typeof character === "string") {
character.toUpperCase(); // コンパイルエラーにならない
}
typescript
const abc: string[] = ["a", "b", "c"];
const character = abc[0];
// 絞り込み条件
if (typeof character === "string") {
character.toUpperCase(); // コンパイルエラーにならない
}

配列要素へのアクセスを安全にするために、noUncheckedIndexedAccessを有効にしておくことを推奨します。