TypeScript 从数组中过滤掉空值 [英] TypeScript filter out nulls from an array

查看:76
本文介绍了TypeScript 从数组中过滤掉空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TypeScript,--strictNullChecks 模式.

TypeScript, --strictNullChecks mode.

假设我有一个可空字符串数组 (string | null)[].什么是单表达式以这样的方式删除所有空值的方法,即结果具有字符串[]类型?

Suppose I have an array of nullable strings (string | null)[]. What would be a single-expression way to remove all nulls in a such a way that the result has type string[]?

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

Array.filter 在这里不起作用:

Array.filter does not work here:

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

数组推导式可能有效,但 TypeScript 不支持它们.

Array comprehensions could've work but they are not supported by TypeScript.

实际上,该问题可以推广到通过从联合中删除具有一种特定类型的条目来过滤任何联合类型的数组的问题.但让我们关注具有 null 和可能未定义的联合,因为这些是最常见的用例.

Actually the question can be generalized to the problem of filtering an array of any union type by removing entries having one particular type from the union. But let's focus on unions with null and perhaps undefined as these are the most common usecases.

推荐答案

您可以使用 .filter 中的类型谓词 函数,以避免选择退出严格的类型检查:

You can use a type predicate function in the .filter to avoid opting out of strict type checking:

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(...).

2021 年更新:更严格的谓词

虽然此解决方案适用于大多数场景,但您可以在谓词中进行更严格的类型检查.正如所介绍的,函数 notEmpty 实际上并不保证它在编译时正确识别值是 null 还是 undefined.例如,尝试将其 return 语句缩短为 return value !== null;,您将不会看到编译器错误,即使该函数会错误地返回 true未定义.

While this solution works in most scenarios, you can get a more rigorous type check in the predicate. As presented, the function notEmpty does not actually guarantee that it identifies correctly whether the value is null or undefined at compile time. For example, try shortening its return statement down to return value !== null;, and you'll see no compiler error, even though the function will incorrectly return true on undefined.

缓解这种情况的一种方法是首先使用控制流块来约束类型,然后使用虚拟变量为编译器提供一些检查.在下面的示例中,编译器能够在到达赋值时推断 value 参数不能是 nullundefined.但是,如果您删除 ||value === undefined 来自 if 条件,您将看到编译器错误,通知您上面示例中的错误.

One way to mitigate this is to constrain the type first using control flow blocks, and then to use a dummy variable to give the compiler something to check. In the example below, the compiler is able to infer that the value parameter cannot be a null or undefined by the time it gets to the assignment. However, if you remove || value === undefined from the if condition, you will see a compiler error, informing you of the bug in the example above.

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

请注意:在某些情况下,此方法仍然可能使您失败.请务必注意与逆变相关的问题.

A word of caution: there exist situations where this method can still fail you. Be sure to be mindful of issues associated with contravariance.

这篇关于TypeScript 从数组中过滤掉空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆