Skip to content

Cannot bracket-index into an object after checking it's existence on that object. #44117

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

Open
h-joo opened this issue May 17, 2021 · 4 comments
Assignees
Labels
Breaking Change Would introduce errors in existing code

Comments

@h-joo
Copy link
Contributor

h-joo commented May 17, 2021

Bug Report

Cannot bracket-index into an object after checking it's existence on that object.

The same failure was reported in #43651, but I couldn't find a separate discussion or a ticket for this.

🔎 Search Terms

  • implicitly has an 'any' type
  • bracket indexing

🕗 Version & Regression Information

Worked in 4.2.4. Starts to break since 4.3.0-beta

⏯ Playground Link

Playground link

💻 Code

interface A {}
function foo(a:A) {
    if ('abc' in a) {
        const z = a;
        // Element implicitly has an 'any' type because expression of type '"abc"' can't be used to index type 'A'.
        // Property 'abc' does not exist on type 'A'.
        return z['abc']; 
    }
}

🙁 Actual behavior

Compiler gives an error that you cannot index into type 'A', since 'abc' does not exist in type 'A'

🙂 Expected behavior

Compiler recognizes the existence check and does not give an error.

Observation

This seems to be caused by the improvement in the control flow analysis/type inference. Before the type of z in the below example was 'never' prior to TS4.3, but now the compiler recognizes z being type A

Question : I have one question though, is it by design that it's allowed to index into never types?

@MartinJohns
Copy link
Contributor

See #34867.

@DanielRosenwasser
Copy link
Member

Yeah but this worked before - @ahejlsberg sounds like we need to at least document this as a breaking change unless we believe it's a regression.

@ahejlsberg
Copy link
Member

The current behavior seems right to me, but I'm not sure what caused the change.

@ahejlsberg
Copy link
Member

Caused by #38610, which is specifically about not narrowing to never. As I said above, I think the current behavior is more desirable, but I suppose it is a breaking change. But really, anything relying on the old behavior seems suspicious given that you can index never with anything and not see an error. The issue that #38610 fixes is that never isn't a correct reflection of the in check. The check absolutely could succeed since pretty much anything is assignable to {}.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Breaking Change Would introduce errors in existing code
Projects
None yet
Development

No branches or pull requests

5 participants