1. ホーム
  2. タイプスクリプト

[解決済み】TypeScriptで配列からNULLをフィルタリングする

2022-04-09 17:22:05

質問

TypeScriptです。 --strictNullChecks モードを使用します。

null可能な文字列の配列があるとします。 (string | null)[] . はどうなるのでしょうか? 単一表現 という型を持つように、すべてのヌルを削除する方法です。 string[] ?

const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = ???;

Array.filterはここでは動作しません。

// Type '(string | null)[]' is not assignable to type 'string[]'
array.filter(x => x != null);

配列内包は使えるかもしれないが、TypeScriptではサポートされていない。

実はこの問題は、任意のユニオン型の配列をフィルタリングして、ユニオンから特定の型を持つエントリを削除する問題に一般化することができます。しかし、最も一般的な使用例である、nullやundefinedを含むユニオンに焦点を当てましょう。

解決方法は?

を使用することができます。 型述語 関数で .filter を使用することで、厳密な型チェックから外れることを防いでいます。

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
    return value !== null && value !== undefined;
}

const array: (string | null)[] = ['foo', 'bar', null, 'zoo', null];
const filteredArray: string[] = array.filter(notEmpty);

あるいは array.reduce<string[]>(...) .

2021年アップデート:述語の厳格化

この解決策はほとんどのシナリオで機能しますが、述語でより厳密な型チェックを行うことができます。提示されたように、関数 notEmpty であるかどうかを正しく識別することを保証するものではありません。 null または undefined をコンパイル時に指定します。例えば、returnステートメントを以下のように短くしてみてください。 return value !== null; この場合、コンパイラのエラーは発生しません。 trueundefined .

これを軽減する一つの方法は、まずコントロールフローブロックを使って型を制約し、次にダミー変数を使ってコンパイラにチェックさせることである。以下の例では、コンパイラは、ダミーの変数が value パラメータは null または undefined を、アサインメントに到達するまでに しかし、もし || value === undefined というエラーが表示され、上の例のバグがあることがわかります。

function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
  if (value === null || value === undefined) return false;
  const testDummy: TValue = value;
  return true;
}

注意:この方法でも失敗する場合があります。に関する問題に注意する必要があります。 反比例 .