Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to use type predicates when using Array.filter with arrow function

I have problem with using type predicates with arrow function.

// this working good 
function filterUndefined1<T>(x: T | undefined): x is T {
  return !x;
}
[1, undefined, 3, 5, undefined].filter(filterUndefined1);


// Retrun Type Error
type FilterUndefined2 = <T>(x: T | undefined) => x is T;
const filterUndefined2: FilterUndefined2 = (x: string) => !x;

// What I want to do
[1, undefined, 3, 5, undefined].filter(filterUndefined2);

// this working good
[1, undefined, 3, 5].filter(<T>(z: T | undefined): z is T => !z);

Why does my arrow function cause a type error when it leaves the filter argument?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

All the is T assertions are lying, the code ensures that the values are falsy instead.

To fix the filterUndefined2 declaration the corresponding type’s generic parameter should be moved and the argument has to match the type; string does not match T | undefined.

type FilterUndefined2<T> = (x: T | undefined) => x is undefined;
const filterUndefined2: FilterUndefined2<string> =
    (x: string | undefined): x is undefined => !x;

This is still wrong for the usage with the example array, though, because that does not contain strings. Hence, this would work:

type FilterUndefined2<T> = (x: T | undefined) => x is undefined;
const filterUndefined2: FilterUndefined2<number> =
    (x: number | undefined): x is undefined => !x;
console.log([1, undefined, 3, 5, undefined].filter(filterUndefined2));

If you actually want to keep the values, which would make more sense, you can invert again using ! or just do something like x != null.

type FilterUndefined2<T> = (x: T | undefined) => x is T;
const filterUndefined2: FilterUndefined2<number> =
    (x: number | undefined): x is number => !!x;
console.log([1, undefined, 3, 5, undefined].filter(filterUndefined2));
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading