LoginSignup
5
2

More than 3 years have passed since last update.

TypeScriptのArray.filterでタイプガードが効かない時の対処

Last updated at Posted at 2019-09-04

例えば、

type HOGE = PIYO | undefined;

と言うような型があったとして、Typescriptの場合ifやcase文でPIYO型として処理を行うことが出来る。

//hogeはHoge型の変数とする

if(hoge){
  //この中ではhogeはpiyo型として扱える
}

一方で、Array.filterではそのような絞り込みは行われない

//hogeArrayはHoge型の配列とする
hogeArray.filter(hoge => !!hoge); //これの戻り値はPIYO[] ではなく HOGE []

ちょっと使い勝手が悪い。

対応策

ユーザー定義TypeGuardを使う

変数名 is 型名 を戻り値に書く関数で任意の方法でTypeGuardをかけられるが、
これを使うパターンだとfilterでもTypeGuardがかかる

const isPIYO = (hoge:HOGE): hoge is PIYO => {
 return !!hoge;
}

ただし、この方法だとコンパイルは通るものの、
実質キャストをかけているだけなので、isPIYOの中身が正しいかどうか静的チェックがかかるわけではない。
isPIYOの実装を間違えていると実行時に型で防げたはずのエラーが出る可能性がある。

flatMapを使う

他にも似たような方法はいくつかあるものの、結局どこかしらでキャストをかけることになる。
そこで、静的型チェックがかかったままfilterと同じことが出来ないか色々試した結果、flatMapで何とかなるということを発見した。

hogeArray.flatMap(hoge => !!hoge ? [hoge]:[]);//戻り値はPIYO配列

ただ、filter後につなげる処理がmapだった場合はまだしも、
純粋にfilter用途でこれをやると気持ち悪いかも知れない。

また、Array.flatMapはES2019の機能なので生TypeScriptでは使えない。
Babel辺りと組み合わせて使う必要がある。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2