Skip to content

Possible bug with undefined narrowing via type guards with conditions #52877

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
ngouy opened this issue Feb 20, 2023 · 4 comments
Closed

Possible bug with undefined narrowing via type guards with conditions #52877

ngouy opened this issue Feb 20, 2023 · 4 comments

Comments

@ngouy
Copy link

ngouy commented Feb 20, 2023

Bug Report

πŸ”Ž Search Terms

Typeguard narrowing undefined conditions

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about type guards

⏯ Playground Link

// Welcome to the TypeScript Playground, this is a website
// which gives you a chance to write, share and learn TypeScript.

// You could think of it in three ways:
//
//  - A location to learn TypeScript where nothing can break
//  - A place to experiment with TypeScript syntax, and share the URLs with others
//  - A sandbox to experiment with different compiler features of TypeScript

type rankedObject = {
    rank: number | undefined
}

const foo: rankedObject[] = [
    {rank: 1}, {rank: 4}, {rank: -1}, {rank: undefined}
]

const sortRanks = (element1: rankedObject, element2: rankedObject) => {
    if (element1.rank !== element2.rank) {
        if(element1.rank && !element2.rank) return -1;
        if(!element1.rank && element2.rank) return 1;
        // error here saying: element1|2 is possibily undefined
        return element1.rank - element2.rank;
    }
}

// To learn more about the language, click above in "Examples" or "What's New".
// Otherwise, get started by removing these comments and the world is your playground.
  

Workbench Repro

πŸ’» Code

type rankedObject = {
    rank: number | undefined
}

const foo: rankedObject[] = [
    {rank: 1}, {rank: 4}, {rank: -1}, {rank: undefined}
]

const sortRanks = (element1: rankedObject, element2: rankedObject) => {
    if (element1.rank !== element2.rank) {
        if(element1.rank && !element2.rank) return -1;
        if(!element1.rank && element2.rank) return 1;
        // error here saying: element1|2 is possibily undefined, which is not possible
        return element1.rank - element2.rank;
    }
}

πŸ™ Actual behavior

I have an error saying element1.rank and element2.rank could be undefined
Which is not possible given:
1 - they are not the same
2 - we rulled out (!A && B) and (A && !B)
so the only possibility that left is that A and B are both not undefined

πŸ™‚ Expected behavior

no error, given rank are both defined at this point

@fatcerberus
Copy link

That this doesn’t work falls under the same reasoning as #52822 (comment). tsc is not a proof solver.

@MartinJohns
Copy link
Contributor

Duplicate of #37258.

@ngouy ngouy closed this as completed Feb 20, 2023
@ngouy
Copy link
Author

ngouy commented Feb 20, 2023

My bad
Anyway I kinda forgot that the ! was ruling out not only undefined stuff, but also falsy stuff
Sorry

@ngouy
Copy link
Author

ngouy commented Feb 20, 2023

Thank you for your help @MartinJohns and @fatcerberus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants