Skip to content
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

Diagnostic about "left-hand side of a 'for...in' statement" type is out of date #13655

Open
mattmccutchen opened this issue Jan 24, 2017 · 6 comments
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Milestone

Comments

@mattmccutchen
Copy link
Contributor

TypeScript Version: 2.1.5

Now that the left side of a 'for...in' statement is apparently allowed to be keyof the right side, the diagnostic for when the left side has the wrong type needs to be updated to account for that possibility.

(Aside: Is it intentional that the left side won't be inferred to have the keyof type because of the unsoundness described in #12314, but it is allowed to be explicitly declared as that type?)

Code

interface Foo {
  x: number;
  y: string;
}

function scan(f: Foo) {
  let k: number;
  for (k in f) {  // Error: "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."
    console.log(k);
  }
  let k2: keyof Foo;
  for (k2 in f) {  // No error
    console.log(k2);
  }
}

Expected behavior:
Something like "The index type of the right side of a 'for...in' statement must be assignable to the left side" perhaps, with details on the failure of assignability?

Actual behavior:
"The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."

@mhegazy
Copy link
Contributor

mhegazy commented Jan 24, 2017

keyof T is string, so why is this error message wrong?

@mattmccutchen
Copy link
Contributor Author

keyof T is string, so why is this error message wrong?

I assume you meant keyof Foo. I don't think so: when I mouse over k2 in Visual Studio Code, it shows the type as "x" | "y". In any case, if I change the annotation to "x" | "y", there is no error, so the error message stating that the type must be string or any is definitely wrong.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 24, 2017

"x" | "y" is a subtype of string. so saying that k needs to be "x" | "y" | string is more or less the same as saying it should be string.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 24, 2017

also the constraint is not really keyof T where T is the type of the right-hand-side, the constraint is string..

i.e. this is allowed:

  let k: "x" | "y" | "z";
  for (k in f) { 
    console.log(k);
  }

The reason is at run-time , f can have more properties than "x" and "y".

@mattmccutchen
Copy link
Contributor Author

Then how do you explain that let k: "x" is an error, but let k: "x" | "y" | Date is allowed? The rule as implemented appears to be that keyof T must be assignable to the type of the left side, and the diagnostic should reflect that.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label May 24, 2017
@RyanCavanaugh RyanCavanaugh added Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels Jul 23, 2019
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jul 23, 2019
@RyanCavanaugh
Copy link
Member

Seems to not be a problem in practice but we'd take a PR if someone wrote a good improvement on the existing message

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants