将 Array.filter 与箭头函数一起使用时如何使用类型谓词

How to use type predicates when using Array.filter 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);

为什么我的箭头函数在离开过滤器参数时会导致类型错误?

所有 is T 断言都在撒谎,代码确保这些值是假的。

要修复 filterUndefined2 声明,应移动相应类型的泛型参数,并且参数必须与类型相匹配; string 不匹配 T | undefined.

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

不过,对于示例数组的用法仍然是错误的,因为它不包含字符串。因此,这会起作用:

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));

如果你真的想保留这些值,这会更有意义,你可以使用 ! 再次反转或只做类似 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));