😽

JSの配列要素にアクセスするときは添字指定をやめてatメソッドを使おう

2024/09/27に公開2

社内で「Arrayの要素を指定するときは [i]やめて.at(i)を使おう」という内容の雑談をしていました.

添字指定に感じていた課題

添字指定でもatメソッドでもどちらもArrayの要素を取得できるメソッドであることに変わりはないのですが,TypeScript上で添字指定した場合はundefinedが返ってくる可能性が推論されないということに課題を感じていました.

TS Playground

const arr: string[] = [];
const str: string = arr[0]; // OK
console.log(str); // undefined

この例では,1行目で空のstring[]を作成していますが,2行目で最初の要素を取得するとstring | undefinedではなくstringと推論されてしまいます.
ところが,実際に実行するとstrの中身はundefinedであることがわかります.

一般的な習慣として,配列へアクセスする際はその値があるかどうかをチェックするコードを書きます.

const arr: string[] = [];
const str: string = arr[0]; // OK
if (str) console.log(str);

ただ,TypeScript上でStringと推論されているものに対してわざわざチェックコードを書くということに個人的に気持ち悪さを感じているという課題がありました.

正しい型情報を付与したい

添字指定の場合に正しい推論を行えるようにするにはどうしたら良いでしょうか?
方法の一つとして,明示的にT | undefinedにアサーションする方法があります.

 const arr: string[] = [];
-const str: string = arr[0];
+const str = arr[0] as string | undefined;
 if (str) console.log(str);

もしくは次のように書くこともできます.

 const arr: string[] = [];
-const str: string = arr[0];
+const str: string | undefined = arr[0];
 if (str) console.log(str);

添字指定をやめたい

型アサーションは現実(JavaScript)と理想(TypeScript)との不都合を良い感じにできる強力な方法ですが,添字指定を利用し続ける以上どうしてもミスが発生する可能性があります.

そこで,代わりに配列から要素を取り出してくれる補助関数を用意し,補助関数を経由して配列から要素を取り出すようにすることで,毎度型アサーションをする必要がなくなり,期待する推論結果を得ることができます.

 const arr: string[] = [];
-const str: string = arr[0];
+const str = arrayAt(arr, 0);
 if (str) console.log(str);
 
+function arrayAt<T>(arr: T[], i: number): T | undefined {
+    return arr[i];
+}

Array.prototype.atを使おう

補助関数を利用する方法も紹介しましたが,atメソッドを使いましょう.
atメソッドは2022年3月時点の主要ブラウザで広くサポートされているほか,TypeScript上でも推論結果がT | undefinedになってくれるまさに欲しかったメソッドです.

 const arr: string[] = [];
-const str: string = arr[0];
+const str = arr.at(0); // string | undefined
 if (str) console.log(str);

添字指定をやめてatメソッドを使うだけで,string型の変数に代入しようとした場合は期待する型エラーを取得することができます.

const arr: string[] = [];
const str: string = arr.at(0); // Type 'undefined' is not assignable to type 'string'.

配列の最後の要素を取得しやすい

また,atメソッドは添字となる値にマイナス値を指定して行くことで最後の要素から順にアクセスできるようになっています.
そのため,次のようにコードの記述量を減らすこともできます.

-const str: string | undefined = arr[arr.length - 1];
+const str = arr.at(-1);

どのバージョンから使えるの?

2022年3月時点で広くブラウザでサポートされている記法なため,よほど古い実行環境でなければatメソッドは普通に使うことができます.

TypeScriptも,4.6以上でes2022以上をターゲットにすることで型推論が行われます.

株式会社モニクル

Discussion