TypeScript,——strictNullChecks模式。
假设我有一个可空字符串数组(string | null)[]。什么是单表达式的方式,以这样的方式删除所有的空值,结果有类型字符串[]?
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = ???;
数组中。过滤器在这里不起作用:
// Type '(string | null)[]' is not assignable to type 'string[]'
array.filter(x => x != null);
数组推导式可以工作,但TypeScript不支持。
实际上,这个问题可以推广为通过从联合中删除具有特定类型的项来过滤任何联合类型的数组的问题。但是让我们关注带有null和可能未定义的联合,因为这些是最常见的用例。
如果您已经使用了Lodash,您可以使用compact。
或者,如果你喜欢Ramda, Ramda的附属品也有紧凑的功能。
两者都有类型,所以您的tsc会很高兴,并得到正确的类型。
从Lodash d.ts文件:
/**
* Creates an array with all falsey values removed. The values false, null, 0, "", undefined, and NaN are
* falsey.
*
* @param array The array to compact.
* @return Returns the new array of filtered values.
*/
compact<T>(array: List<T | null | undefined | false | "" | 0> | null | undefined): T[];
结合上面我最喜欢的答案之一,与一些通用技巧和对Array接口的扩展,我能够做出一个全局定义,添加到您的模块后,允许任何数组被“压扁”,删除所有空值替换(任何|undefined|null)[]与任何[]。
mixedarray . squash()适合链接和映射。
只需在模块的某个地方添加这段代码(可以随意省略eslint的东西,但我的set在这里的一些事情让我感到困扰):
/* eslint-disable no-unused-vars */
/* eslint-disable no-extend-native */
declare global {
interface Array<T> {
squish<NonNull, Nullable extends (NonNull | undefined | null)>(): NonNull[];
}
}
if (!Array.prototype.squish) {
Array.prototype.squish = function squish<NonNull, T extends(NonNull|undefined|null)>
(this: T[]): NonNull[] {
return this.flatMap((e) => (e ? [e] : [])) as NonNull[]
}
}