Flowtype - generic array

How i can write generic function, which take Array of Objects (any type of Object, possible even null and undefined), and filter it to return just valid items of array? If i write it lite this, i will lose genericity :/

// @flow

// Types
type Person = {
  id: string,
  name: string,
};

type Car = {
  id: string,
  color: string,
};

// Function definition
const isNotUndefinedOrNull = item => !(item === null || item === undefined);

export const trimList = (list: Array<any> | $ReadOnlyArray<any>): Array<any> => {
  return list.filter(isNotUndefinedOrNull);
};

// Constants
const persons = [{ id: 'p1', name: 'Johny' }, null, undefined];
const cars = [{ id: 'c1', color: 'red' }, null, undefined];

// Calls
const trimmedPersons = trimList(persons);
const trimmedCars = trimList(cars);

PROBLEM is, there i have trimmed cars and persons, but flow doesnt know, there is Cars in the trimmedCars list and neither know there is Persons in trimmedPersons list. Flow see just Array and i dont know, how to write is right, to not lose this info. Flow try

Upvotes: 1

Views: 616

Answers (2)

i found it :)

export function trimList<V>(list: Array<?V> | $ReadOnlyArray<?V>): Array<V> {
  return R.filter(isNotUndefinedOrNull, list);
}

Upvotes: 0

Buggy
Buggy

Reputation: 3649

As flow has a bug with Refine array types using filter we use explicit type casting ((res): any): T[]).

function filterNullable<T>(items: (?T)[]): T[] {
    const res = items.filter(item => !(item === null || item === undefined);
    return ((res): any): T[]);
}

// Example
const a: number[] = filterNullable([1, 2, null, undefined]);

Upvotes: 0

Related Questions