TypeScript 从数组中过滤掉空值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43118692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript filter out nulls from an array
提问by SergeyS
TypeScript, --strictNullChecks mode.
打字稿,--strictNullChecks 模式。
Suppose I have an array of nullable strings (string | null)[]. What would be a single-expressionway to remove all nulls in a such a way that the result has type string[]?
假设我有一个可空字符串数组 (string | null)[]。以结果具有字符串 [] 类型的方式删除所有空值的单表达式方法是什么?
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = ???;
Array.filter does not work here:
Array.filter 在这里不起作用:
// Type '(string | null)[]' is not assignable to type 'string[]'
array.filter(x => x != null);
Array comprehensions could've work but they are not supported by TypeScript.
数组推导式可能有效,但 TypeScript 不支持它们。
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.
实际上,该问题可以推广到通过从联合中删除具有一种特定类型的条目来过滤任何联合类型的数组的问题。但是让我们关注具有 null 和可能未定义的联合,因为这些是最常见的用例。
回答by Bijou Trouvaille
You can use a type predicatefunction in the .filter
to avoid opting out of strict type checking:
您可以在 中使用类型谓词函数.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);
Alternatively you can use array.reduce<string[]>(...)
.
或者,您可以使用array.reduce<string[]>(...)
.
回答by alukach
Similar to @bijou-trouvaille's answer, you just need to declare the <arg> is <Type>
as the output of the filter function:
与@bijou-trouvaille 的回答类似,您只需将 声明<arg> is <Type>
为过滤器函数的输出:
array.filter((x): x is MyType => x !== null);
回答by Nitzan Tomer
You can cast your filter
result into the type you want:
您可以将filter
结果转换为您想要的类型:
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(x => x != null) as string[];
This works for the more general use case that you mentioned, for example:
这适用于您提到的更一般的用例,例如:
const array2: (string | number)[] = ["str1", 1, "str2", 2];
const onlyStrings = array2.filter(x => typeof x === "string") as string[];
const onlyNumbers = array2.filter(x => typeof x === "number") as number[];
(操场上的代码)
回答by Mike Sukmanowsky
One more for good measure as people often forget about flatMap
which can handle filter
and map
in one go (this also doesn't require any casting to string[]
):
还有一对,因为人们往往忽视了很好的措施flatMap
,它可以处理filter
和map
一气呵成(这也并不需要任何铸造string[]
):
// (string | null)[]
const arr = ["a", null, "b", "c"];
// string[]
const stringsOnly = arr.flatMap(f => typeof f === "string" ? [f] : []);
回答by Digvijay
I believe you have it all good except that the type checking just makes the filtered type not be different than the return type.
我相信你一切都很好,只是类型检查只是使过滤类型与返回类型没有区别。
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = array.filter(f => f !== undefined && f !== null) as any;
console.log(filterdArray);
回答by Sourodeep Chatterjee
I think this will be an easy approach, with more cleaner code
我认为这将是一种简单的方法,代码更清晰
const array: (string | null)[] = ['foo', 'bar', null, 'zoo', null];
const filteredArray: string[] = array.filter(a => !!a);
回答by Robert Massaioli
To avoid everybody having to write the same type guard helper functions over and over again I bundled functions called isPresent
, isDefined
and isFilled
into a helper library: https://www.npmjs.com/package/ts-is-present
为了避免大家不必编写同一类型的后卫辅助函数一遍一遍我捆起调用的函数isPresent
,isDefined
并isFilled
进入一个辅助库:https://www.npmjs.com/package/ts-is-present
The type definitions are currently:
类型定义目前是:
export declare function isPresent<T>(t: T | undefined | null): t is T;
export declare function isDefined<T>(t: T | undefined): t is T;
export declare function isFilled<T>(t: T | null): t is T;
You can use this like so:
您可以像这样使用它:
import { isDefined } from 'ts-is-present';
type TestData = {
data: string;
};
const results: Array<TestData | undefined> = [
{ data: 'hello' },
undefined,
{ data: 'world' }
];
const definedResults: Array<TestData> = results.filter(isDefined);
console.log(definedResults);
When Typescript bundles this functionality in I'll remove the package. But, for now, enjoy.
当 Typescript 捆绑此功能时,我将删除该包。但是,现在,享受吧。
回答by Akitha_MJ
If you are checking null with other conditions using filter simply this can be used hope this helps for some one who is looking solutions for an object array
如果您正在使用过滤器检查其他条件的空值,则可以使用它,希望这对正在寻找解决方案的人有所帮助 object array
array.filter(x => x != null);
array.filter(x => (x != null) && (x.name == 'Tom'));