Skip to content

Type predicate assertion does not carry over when used in another function #51326

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
yogiduzit opened this issue Oct 27, 2022 · 4 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@yogiduzit
Copy link

Bug Report

🔎 Search Terms

  • predicate
  • type predicate
  • type predicate return

🕗 Version & Regression Information

  • This is NOT a crash
  • This changed between versions ______ and _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______

⏯ Playground Link

Playground link with relevant code

💻 Code

interface Animal {
  name: string;
}

interface Bird extends Animal {
  wingSpan: string;
}

/**
 * Asserts that an animal is of type T if condition is true for that animal.
 */
function isAnimalOfType<T extends Animal>(animal: Animal, condition: (animal: T) => boolean): animal is T {
  return condition(animal as T);
}

function isBird(animal: Animal) {
  return isAnimalOfType<Bird>(animal, (bird) => Boolean(bird.wingSpan));
}

function getWingspan(bird: Bird) {
  return bird.wingSpan;
}

const animals = [{ name: "a" }, { name: "a", wings: "3ft" }] as Animal[];

function checkAnimals(animals: Animal[]) {
  return animals.map(animal => {
    console.log(animal);
    if (isBird(animal)) {
      console.log(getWingspan(animal));
    }
  })
}

🙁 Actual behavior

The call to getWingspan shows an error saying Argument of type 'Animal' is not assignable to parameter of type 'Bird'.

🙂 Expected behavior

The function isAnimalOfType already asserts that the Animal will be of type T. So, why does isBird not automatically assert that?

@fatcerberus
Copy link

Type predicates are not automatically inferred. You need to explicitly declare isBird as returning animal is Bird.

@jcalz
Copy link
Contributor

jcalz commented Oct 27, 2022

Duplicate of #10734

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Oct 27, 2022
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@danvk
Copy link
Contributor

danvk commented May 15, 2024

This was marked as a duplicate of #10734, which was closed by #57465. But that PR only let "identifier" type predicates flow, not assertion predicates. The example in this issue is still broken.

This specific issue would be fixed by #58495, see playground.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

6 participants