Skip to content

Simple inversion of && causes types to stop being valid, even though the js execution is the same #63474

@danon

Description

@danon

🔎 Search Terms

I think both of these notations should yield the same result.

function f4 (obj: object, field: 'start'|'end') {
    if (field === 'start' && field in obj) {
        obj[field]
    }
    throw new Error();
}

function f5 (obj: object, field: 'start'|'end') {
    if (field in obj && field === 'start') {
        obj[field]
    }
    throw new Error();
}

But actually one of them is marked as valid and the other as not:

Image

Same thing happens with two nested ifs if you just invert them.

Reproduction: https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABMALIgFHARgKwFyLY4Cm0ANMjMQDYAmBA5AM5QCGATlAwD4PFi0GASkQBvAFCIpiGMAzAqdRAF5ViZm04NEAMh2UatGUiIiJ0i4VwBtBYYC6k6QF8nUqAAt2cAO6IwxH4Aouze7OhCANziruKgkLAIyACsGEQERKRQFHZ0jCwcXLz8gmZuMnLouUYwJri6+tUqahqFwmLlFkS2irSOFq4Wnt5+AcGhcOFRMeJAA

🕗 Version & Regression Information

  • This changed between versions 4.8.4 and 4.9.5 - At 4.8.4 and before both of these were invalid.
  • This changed in commit or PR _______
  • 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

No response

💻 Code

function f1(obj: object, field: 'start'|'end') {
    if (field === 'start' && field in obj) {
        obj[field]
    }
    throw new Error();
}

function f2(obj: object, field: 'start'|'end') {
    if (field in obj && field === 'start') {
        obj[field]
    }
    throw new Error();
}

🙁 Actual behavior

It reports as erroneous, even tough I think it's a valid code.

🙂 Expected behavior

Both of these should be accepted as valid.

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions