Home > Mobile >  Using type predicates does not return the right type in TypScript 4.7.3
Using type predicates does not return the right type in TypScript 4.7.3

Time:06-16

In the following example, I am using a user-defined type guard function in order to filter an array. I want a strongly typed array of only Fish.

The type are properly returned here, please note I am using a point free style:

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

The type are not properly returned here, It is a mixed array:

const onlyFish2 = animals.filter(x => isFish(x)); // (Fish | Bird)[]
  • Why there is this different?
  • How do you ensure the types are properly returned in onlyFish2 without doing 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)[]

CodePudding user response:

The difference is the following:

const onlyFish = animals.filter(isFish);

Here, the result of the predicate will be x is Fish and as such TypeScript can correctly deduce the type.

However, in this case:

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

The return value of your predicate is a boolean as you are returning the result from your type guard: "is x a Fish?".

  • Related