在下面的示例中,我使用用户定义的类型保护函数来过滤array.我想要一个只有Fish的强类型array.

此处正确返回了类型,请注意,我使用的是无点样式:

const onlyFish = animals.filter(isFish); // Fish[]

此处未正确返回类型,它是一个混合数组:

const onlyFish2 = animals.filter(x => isFish(x)); // (Fish | Bird)[]
  • 为什么会有这种不同?
  • 如何确保只在onlyFish2中正确返回类型,而不执行const onlyFish2: Fish[]

TS playground

    type Fish = {
        variant: 'fish'
    }
    
    type Bird = {
        variant: 'bird'
    }
    
    const isFish = (animal: Fish | Bird): animal is Fish => animal.variant === 'fish';
    
    const animals: ReadonlyArray<Fish | Bird> = [{ variant: 'fish' }, { variant: 'bird' }];
    
    const onlyFish = animals.filter(isFish); // Fish[]
    
    const onlyFish2 = animals.filter(x => isFish(x)); // (Fish | Bird)[]

推荐答案

区别如下:

const onlyFish = animals.filter(isFish);

这里,谓词的结果将是x is Fish,因此TypeScript可以正确推断类型.

然而,在这种情况下:

const onlyFish2 = animals.filter(x => isFish(x));

当您从类型guard:"is x a Fish?"返回结果时,谓词的返回值是boolean.

Typescript相关问答推荐

typescript抱怨值可以是未定义的,尽管类型没有定义

在TypeScript中使用泛型的灵活返回值类型

我应该使用什么类型的React表单onsubmit事件?

为什么typescript不能推断类的方法返回类型为泛型''

如何在TypeScrip面向对象程序设计中用方法/属性有条件地扩展类

React typescribe Jest调用函数

如何在typescript中设置对象分配时的键类型和值类型

如何编写一个类型脚本函数,将一个对象映射(转换)为另一个对象并推断返回类型?

如何判断对象是否有重叠的叶子并产生有用的错误消息

MatTool提示在角垫工作台中不起作用

如何以Angular 导入其他组件S配置文件

为什么Typescript只在调用方提供显式泛型类型参数时推断此函数的返回类型?

将超类型断言为类型脚本中的泛型参数

从类型脚本中元组的尾部获取第n个类型

如果判断空值,则基本类型Gaurd不起作用

在单独的组件中定义React Router路由

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

我如何键入它,以便具有字符串或数字构造函数的数组可以作为字符串或数字键入s或n

基于泛型类型的条件类型,具有条目属性判断

如何解决联合类型上的此表达式不可调用?