const scores = ids.map((id) => scoreMap.get(id)).filter((s) => !!s) と書いたのに、scores が (number | undefined)[] のままで、合計を出すところでエラーになります。どうしますか。
filter((s) => !!s) は 0 も消すので、TypeScript は型を絞り込みません。s !== undefined と書けば、5.5 以降は型述語が推論されて number[] になります。0 が消える不具合も防げます。
面接官が見ているのはTypeScript が型を絞らない理由が、実際の不具合(0 を落とす)だと気づけるか。
よくある答えと、面談でどう見られるか
- !!s だと 0 点も消えてしまう。.filter((s) => s !== undefined) に直す。5.5 以降なら、これで number[] に絞り込まれる
その通りです。公式のリリースノートが、まさにこの例を「本物の不具合」として挙げています。 - .filter((s): s is number => !!s) と型述語を書く
型は通りますが、0 点が消える不具合は残ったままです。TypeScript は型述語の中身が正しいかを確かめません。 - as number[] を付ける
型は通りますが、0 点が消える不具合はそのままです。 - TypeScript が filter を理解できない制限なので、! を付けて使う
制限ではありません。0 を消してしまうので、TypeScript はわざと絞り込んでいません。
模範解答
undefined だけを外すように、.filter((s) => s !== undefined) と書きます。
!!s は、undefined だけでなく 0 も偽として外します。0 点の人がいれば、その人の点数が消え、平均が上振れします。
TypeScript 5.5 から、filter に渡した関数から型述語(s is number)が推論されるようになりました。ただし「true なら number、false なら number ではない」と言い切れるときだけです。!!s は false のときに 0(number)もありうるので、推論されません。公式のリリースノートは、まさにこの例を挙げて「本物の不具合」だと説明しています。
s !== undefined なら言い切れるので、scores は number[] になります。
出典(一次資料)
対象: TypeScript 5.x〜7.0 照合した一次資料: 公式ドキュメント 照合: 2026-10-25 最終更新: 2026-10-25
お使いの版で挙動が違う場合があります。誤りに気づいたらこの解説を報告するから教えてください。
ここからどう深掘りされるか
この問いに答えられた場合、面談は次の質問に進みます。