Skip to content

excluded type narrowing #47919

New issue

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

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

Already on GitHub? Sign in to your account

Closed
jonnytest1 opened this issue Feb 16, 2022 · 2 comments
Closed

excluded type narrowing #47919

jonnytest1 opened this issue Feb 16, 2022 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@jonnytest1
Copy link

Bug Report

🔎 Search Terms

type narrowing

🕗 Version & Regression Information

  • This is 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

class A {
    a() { }
}

let el: A | string
let el2: A | string

if (el instanceof A || el2 instanceof A) {
    if (el instanceof A && el2 instanceof A) {


    } else if (el instanceof A) {
        el2 // string | A
    }
}

🙁 Actual behavior

if el or el2 are instance of A
AND
! (el and el2) instance of A
AND
el isntance of A
then el2 can only be string - but is shown as string|A

🙂 Expected behavior

(😅 i know its over the top )
but if possible i would like el2 to be narrowed down to string

@MartinJohns
Copy link
Contributor

This sounds like a duplicate of #37258.

@fatcerberus
Copy link

fatcerberus commented Feb 16, 2022

Yeah so the problem here is that narrowing is done for each expression individually and el instanceof A || el2 instanceof A doesn't give the compiler enough information to narrow either one (one of them is an A, but which one?). When it gets the && check it can narrow that (it now knows both are As), but it can't do anything in the else clause because at that point the compiler would have to look backwards at both past type checks to actually narrow something.

TS doensn't internally track type guards as such--a guard either narrows a type or it doesn't, and then the compiler moves on. Further narrowings are based only on the types they are given as input.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Feb 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants