简体   繁体   English

如何在 TypeScript 中定义过滤数组

[英]How to define filtered array in TypeScript

I have an array with two possible values.我有一个包含两个可能值的数组。 It might include an expected object, or an object which defines an error.它可能包括预期的 object 或定义错误的 object。 The data could look something like this:数据可能如下所示:

// mixedData
[
    { item1: "value", item2: "value2" },
    { error: true, description: "no value found" },
];

I made two types for this array.我为这个数组制作了两种类型。 One for a valid object and one for the error object.一个用于有效 object,一个用于错误 object。 I then defined my array like this:然后我像这样定义我的数组:

const myArray: Array<IValid | IError> = [] // fetched from api

Next I want to remove every object with an error field from the array, leaving me with IValid objects only:接下来,我想从数组中删除每个带有错误字段的 object,只留下IValid对象:

const filteredData: IValid[] = mixedData.filter(
    (obj: IValid | IError) => !obj.hasOwnProperty("error")
);

This works but TypeScript does not really like this because it still thinks an item could be of IError :这可行,但 TypeScript 并不真正喜欢这个,因为它仍然认为一个项目可能是IError

Error: Type '(IValid| IError)[]' is not assignable to type 'IValid[]'.

How do I make TypeScript happy here?如何让 TypeScript 在这里开心?

Just cast to validData[].只需转换为validData []。

const filteredData: validData[] = mixedData.filter((obj: IValid | IError) => !obj.hasOwnProperty('error')) as validData[];

You can just use typeguard as a filter predicate:您可以只使用 typeguard 作为filter谓词:

type IValid = { item1: string, item2: string }

type IError = { error: boolean, description: string }

type All = IValid | IError

const data: All[] = [
    { item1: 'value', item2: 'value2' },
    { error: true, description: 'no value found' }
]

const myArray: Array<IValid | IError> = [] // fetched from api

const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
    : obj is Obj & Record<Prop, unknown> =>
    Object.prototype.hasOwnProperty.call(obj, prop);

const filteredData = data.filter((obj): obj is IValid /** here is the trick */ => !hasProperty(obj, 'error')); // IValid[]

Playground 操场

Object.prototype.hasOwnProperty.call is much safer than obj.hasOwnProperty , see eslint rule Object.prototype.hasOwnProperty.callobj.hasOwnProperty安全得多,参见eslint 规则

Simple example with Type Guards Type Guards的简单示例

interface IValid { item1: string; item2: string };
interface IError { error: boolean; description: string };

const data: Array<IValid | IError> = [
    { item1: "value", item2: "value2" },
    { error: true, description: "no value found" },
];

function isValid(obj: IValid | IError): obj is IValid {
    return (obj as IError).error === undefined;
}

const filteredValidData = data.filter(isValid);
console.log(filteredValidData);
// [ { item1: "value", item2: "value2" } ]

Other examples from documentation 文档中的其他示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM