🕌
[TypeScript] .filter((x): x is T => ...) を使わずに配列から特定の型を除外する
TypeScript で (string | null)[]
型の配列から null を除外して string[]
型の配列を作るような場合には、array.filter((x): x is string => x !== null)
のように戻り値の型を明示するのが一般的ですが、x is T
形式の宣言は戻り値の型検査が行われないのでできれば避けたいところです。
ES2019 で追加された .flatMap()
を使うと、x is T
を使わず簡単に特定の型の要素のみをフィルタできます。
const array: (string | null)[] = ['a', null, 'b']
const filteredArray: string[] = array.flatMap((x) => (x === null ? [] : [x]))
説明
.flatMap()
は .map()
と .flat()
の処理が合わさったメソッドで、callback 関数内で返却した値をフラットに展開して新しい配列を作ります。
;['1', '2'].flatMap((x) => [`${x}-a`, `${x}-b`]) // => ['1-a', '1-b', '2-a', '2-b']
この応用で、callback で空の配列を返却すると要素を削除することもできるので、array.flatMap((x) => (x === null ? [] : [x]))
は要素が null の場合はその要素を削除し、null でない場合はそのまま残す、という処理を行っているのです。
x === null
が false のとき x
の型は string
なので、callback 関数の戻り値は string[]
になり、結果の配列も string[]
型になるのでキャストを使わずに済みます。
Discussion
勉強になりました。ありがとうございます。サンプルとしてzodのsafeParseでデモ作ってみました。
demo code.
簡単ですが、以上です。