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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:40:17  来源:igfitidea点击:

TypeScript filter out nulls from an array

typescript

提问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 .filterto 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 filterresult 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[];

(code in playground)

操场上的代码

回答by Mike Sukmanowsky

One more for good measure as people often forget about flatMapwhich can handle filterand mapin one go (this also doesn't require any casting to string[]):

还有一对,因为人们往往忽视了很好的措施flatMap,它可以处理filtermap一气呵成(这也并不需要任何铸造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, isDefinedand isFilledinto a helper library: https://www.npmjs.com/package/ts-is-present

为了避免大家不必编写同一类型的后卫辅助函数一遍一遍我捆起调用的函数isPresentisDefinedisFilled进入一个辅助库: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'));