Waka blog.

[Typescript]配列の要素からundefinedを取り除くいくつかの方法

やりたいこと

以下のような配列があったとする

const stringWithUndefinedArray = ["a", "b", undefined, "c", "d"];

この場合、 stringWithUndefinedArray の型は (string | undefined)[] となる。

この状態から string[] に変換したい。

ダメな例

単純に以下のようにfilter関数を呼び出しても型は (string | undefined)[] のまま変わらない。

const stringArray = stringWithUndefinedArray.filter((val) => val != undefined);

解決方法

1. 型アサーションとfilterの組み合わせ

単純にfilterを使うのではなく、以下のように型アサーションと組み合わせることで型からundefinedを取り除くことができる。

const stringArray = stringWithUndefinedArray.filter((val): val is string => val != undefined);

しかし、型アサーションはあくまで実装者がstringであると明示するだけであり、コンパイラ時にエラーを検出してくれるわけではない。

極端な話、以下のようなコードが混入していたとしてもコンパイルエラーにはならず、バグを生む危険性があるのであまり積極的に使わない方が良さそう。

// != ""をフィルタしているので、undefineはそのまま配列に残ってしまう
const stringArray = stringWithUndefinedArray.filter((val): val is string => val != "");

2. 型ガードを使用

typeofを使用してstringであることを保証しているので、確実にstringだけを抽出することができます。型アサーションだけの場合よりもはるかに安全。

const isString = (val: any): val is string => typeof val === "string";

const stringArray = stringWithUndefinedArray.filter(isString);

3. lodash、またはes-toolkitのcompactを使用する

元も子もないけど、安心感はある。

falseになりうる値が除去されるので、bool値のfalseや数値の0も除去されるので使い所を気をつける必要がある。

lodash#compact

es-toolkit#compact

以上。