const arr = ['a', 'b', 'c']
// arr2 is string[]
const arr2 = arr.flatMap((item) => (item === 'a' ? [] : [item]))
// arr3 is Promise<string | never[]>[]
const arr3 = arr.flatMap(async (item) => (item === 'a' ? [] : item))
もっと具体的には条件に応じて非同期処理が入るような場合で、ついついこんな処理を書いてしまいそうですが、これは正しくありません。
const arr4 = arr.flatMap(async (item) => {
if (item === 'a') {
return []
}
await asyncFunc()
return item
})
というのもこれはflatMapの戻り値がPromise<T>になるため、Promise<never[]> | Promise<T>となります。flatMapで空配列を戻せばunnestされて除去したことになるはずですが、Promise<never[]>が戻るため、unnestされません。
ですのでflatMap内に渡す関数は同期的な関数に留め、戻り値が[] | Promise<T>になるようにします。
例えば以下のような構造です。
const arr5 = arr.flatMap((item) => {
if (item === 'a') {
return []
}
return asyncFunc().then(() => item)
})
シンプルな場合はこれでもいいんですが、非同期関数を複数実行する必要がある時など、thenが連続して非常に読みにくい処理になるはずです。
いっそのことmap().filter()で書いちゃった方が実行時間的にも有利だし可読性高いと思う。
コメント