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.filter(Boolean);
这对所有真值都适用。
遗憾的是,这里不提供类型推断,找到了这个解决方案
在这里
type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T; //from lodash
function truthy<T>(value: T): value is Truthy<T> {
return Boolean(value); // or !!value
}
const arr =["hello","felow","developer","",null,undefined];
const truthyArr = arr.filter(truthy);
// the type of truthyArr will be string[]
下面是一个使用NonNullable的解决方案。我发现它甚至比@ bijouu -trouvaille的公认答案更简洁
function notEmpty<TValue>(value: TValue): value is NonNullable<TValue> {
return value !== null && value !== undefined;
}
const array: (string | null | undefined)[] = ['foo', 'bar', null, 'zoo', undefined];
const filteredArray: string[] = array.filter(notEmpty);
console.log(filteredArray)
[LOG]: ["foo", "bar", "zoo"]
或者您可以尝试包:@p4ck93/ts-is
https://www.npmjs.com/package/@p4ck493/ts-is
示例使用CDN方法,但是包也支持typescript。
<script>var exports = {};</script>
<script src="//unpkg.com/@p4ck493/ts-is@3.0.1/dist/index.js"></script>
<script>
const {is} = exports;
console.log('is.string: ', is.string('')); // true
console.log('is.string.empty: ', is.string.empty('')); // true
console.log('is.string.not.empty: ', is.string.not.empty('')); // false
const array = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(is.string.not.empty);
console.log('array:', array);
console.log('filterdArray:', filterdArray);
</script>
UPD
或打字稿:
Import {is} from '@p4ck493/ts-is';
Const array = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(is.string.not.empty);
/**
选择:
array.filter (is.not.null);
array.filter (is.not.empty);
array.filter (is.string);
* * /