配列に filter をかけて必要な値を持っている要素を抜き出すのはよくある処理です。この時、型が filter で望む通りにならず困る時がしばしばあります。例えば、次のコードと画像の様に起きます
const options = [ { label: '未選択', }, { label: 'ほげ', value: 1, }, { label: 'ふが', value: 2, }, ]; options.filter((option) => !!option.value) .forEach((option) => option.value.toFixed(2));
filter で value が未定義の option を弾いたにもかかわらず、未定義の可能性があると怒られます。これを解決するには次の様に is を使い、ユーザ定義の型ガードを作ります。
型ガード – TypeScript Deep Dive 日本語版
type NotNullOption = { label: string; value: 1 | 2 }; const options = [ { label: '未選択', }, { label: 'ほげ', value: 1, }, { label: 'ふが', value: 2, }, ]; options // filter の返り値の bool に is を使って"ある型である"と意味付けします。 .filter((option): option is NotNullOption => !!option.value) // ある型は value: 1|2 なのでコンパイルエラーになりません。 .forEach((option) => option.value.toFixed(2));
こうすると filter が TypeScript 的にも便利になり as や any で型安全を壊して無理矢理動かす様な事態を減らせます。