-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Misleading type hint when narrowed at declaration time #46731
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
Comments
The opposite would be much worse. Just take this example:
Would you expect an error here? Surely not, because you always assign a |
I would expect an error, yes! If we knew |
The narrowing part is a feature, not a bug. See the TS documentation: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#assignments The quick info type display is also as intended but I don’t know of an official doc about it… I’ve seen someone on the TS team mention it before in an issue though. Maybe I can find it. |
@jcalz, that documentation does not explain the case where there is an explicit type annotation on the variable. Why does type inferrence overwrite the type annotation? But regardless, I understand this is a matter of opinion and design. The quick info type display has to be a bug, though. It misrepresents the type of the variable and is inconsistent with the same type hint on the same variable on the next line. |
There's #45870, which is asking for some way to see both the narrowed type and the original type of a narrowed expression. Right now quickinfo shows you a single type for any given expression, so it's going to be "misleading" no matter what; some people (e.g., you) expect to see the annotated type and others expect to see the narrowed type. |
I believe the variable only has one type. It’s the set of values that that variable can hold. The difference between the annotated and the narrowed types is an implementation detail. Ignoring my judgement for a moment, what are the practical benefits of showing the annotated type on declaration? The annotated type is right there already. |
Technically a variable does have two types at any given time, and this is not just an implementation detail: There's the type it's been narrowed to based on control flow analysis, which affects where it can be assigned, and the declared type, which affects what you can assign to it. Both are observable. |
@fatcerberus, fair enough, but that only applies to mutable bindings. For immutable bindings, which are the default, in my opinion, there is only the former. |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Bug Report
🔎 Search Terms
variable declaration, type hint
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about Common "Bugs" That Aren't Bugs and Type System Behavior
Earliest version tested: 3.3.3333
Last version tested: 4.6.0-dev.20211105
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Type hint for
const a
on the line of declaration isFoo
.Type hint for
const a
on the line of use is{ left: string }
.🙂 Expected behavior
Type hint for
const a
on the line of declaration is{ left: string }
, consistent with the type hint on the next line.Showing the type of
a
asFoo
is at least a visual bug. Ifa
isFoo
, how come I can accessa.left
on the next line?As a more opinionated, stronger statement, I would not expect type narrowing here at all. I have very clearly annotated that
a
isFoo
, I don't want any other type to be inferred. I have annotated it asFoo
because probably in the future the value ofa
will be more dynamic and I want to make sure the code below supports that.The text was updated successfully, but these errors were encountered: