1. ホーム
  2. typescript

TypeScriptコンパイラにArray.prototype.filterが配列から特定の型を削除するように伝える方法は?

2023-08-05 05:33:05

質問

Array.prototype.filterを使用して配列からNULL(未定義)要素をフィルタリングしようとしていますが、TypeScriptコンパイラは"filter"関数の派生配列を認識しないようで、型チェックに失敗しています。

以下の単純化したコードを仮定すると、(number|undefined)[]型の配列があり、number[]配列に適合するようにundefinedをフィルタリングしたい場合です。

const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = arry
    .map((i) => {
        return typeof i === "number" ? i : void 0;
    })
    .filter((i) => i);

エラーによると

タイプ '(number | undefined)[]' はタイプ 'number[]' に割り当てられません。 タイプ 'number | undefined' はタイプ 'number' に割り当てられません。 タイプ 'undefined' はタイプ 'number' に割り当てられません。

filter関数がundefinedを除去することを知っている私は、以下のように結果の配列をnumber[]にキャストすることができます。

const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = (arry
    .map((i) => {
        return typeof i === "number" ? i : void 0;
    })
    .filter((i) => i) as Number[]);

キャスト以外の良い方法はないでしょうか?

環境は TSC2.1、strictNullChecksを有効にしています。

どのように解決するのですか?

TypeScriptのUser-Defined Type Guards機能を利用する。

const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = arry
    .filter((i): i is number => {
        return typeof i === "number";
    });
// numArry = [1, 2, 3, 4, 6]

を見てみましょう。 i is number を見てください。 このトリックにより、Array.filterの結果の型をキャストすることができます。