【TypeScript】Array.mapでcontinueするためにfilterでundefinedを型安全に除外する

TypeScriptのArray.map()を使用していると、for文のcontinueのようにスキップし特定の要素を新配列に含めたくないことがある。

type User = {
name: string;
age: number;
};
const users: User[] = [
/* some user objects */
];
const userNames = users.map(({ name }) => {
if (name === '') return; // undefinedが返る
// some logic
});

が上記のようにreturnすると新配列(userNames)にundefinedが格納されてしまう。

解決法

const userNames = users
.map(({ name }) => {
if (name === "") return;
// some logic
})
.filter((name) => name !== undefined);
userNames; // (string | undefined)[]

Array.map()で生成した配列からundefinedを除外する方法が真っ先に挙がる。

しかしArray.filter()だと判定ロジックから返り値の型を推論してくれず、上記のようにundefinedが型から除外されない。

.filter((name) => name !== undefined);
.filter((name):name is Exclude<typeof name, undefined> => name !== undefined);

そこでType predicateを使用し型ガードすることで型問題も解決する。