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

Unexpected type listed in error message #29861

Closed
getify opened this issue Feb 11, 2019 · 10 comments · Fixed by #38049
Closed

Unexpected type listed in error message #29861

getify opened this issue Feb 11, 2019 · 10 comments · Fixed by #38049
Labels
Domain: Error Messages The issue relates to error messaging Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Experience Enhancement Noncontroversial enhancements Fixed A PR has been merged for this issue Help Wanted You can do this Suggestion An idea for TypeScript

Comments

@getify
Copy link

getify commented Feb 11, 2019

TypeScript Version: 3.2? (whatever version is currently on the playground)

Search Terms: "error message", "unexpected", "type", "is not assignable to"

Code

var a = 3;
a = "hello";

vs:

var a = 3;
var b = "hello";
a = b;

Expected behavior:

Expect both error messages to say: "Type 'string' is not assignable to type 'number'."

Actual behavior:

The error message in the first snippet says: "Type '"hello"' is not assignable to type 'number'."

The error message for the second snippet correctly says: "Type 'string' is not assignable to type 'number'."

Playground Link:

Unexpected type listed error message: https://www.typescriptlang.org/play/#src=var%20a%20%3D%203%3B%0D%0Aa%20%3D%20%22hello%22%3B

Expected type listed error message: https://www.typescriptlang.org/play/#src=var%20a%20%3D%203%3B%0D%0Avar%20b%20%3D%20%22hello%22%3B%0D%0Aa%20%3D%20b%3B

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Feb 12, 2019
@getify
Copy link
Author

getify commented Feb 13, 2019

I'm not sure what "working as intended" means. Are you saying that "hello" (including the "s) is a valid type, as the error message implies? It's clearly not.

It really makes no sense to me why TypeScript would, in the second snippet, be able to determine/infer that "hello" is a string type value, so that b should be set as a string variable, but that the same "hello" value doesn't have an inferrable type of string for the purposes of the error message in the first snippet.

It may be that this is a difficult issue or not worth the effort to fix, but I don't understand how "working as intended" is the appropriate label for its triage?

@dragomirtitian
Copy link
Contributor

@getify "hello" is a valid type in typescript. Any literal can also be a type, the concept is called literal types

So when you perform the assignment, the type of "hello" is the string literal type "hello" and thus you get the error.

String literal types get widened to their base type on assignment (except in some cases, for example assignment to const), so when you first assign b = "hello", b will not be typed as the string literal type but rather to string and you get the error you expect.

@getify getify closed this as completed Feb 13, 2019
@getify
Copy link
Author

getify commented Feb 13, 2019

My apologies.

@DanielRosenwasser DanielRosenwasser added Help Wanted You can do this Domain: Error Messages The issue relates to error messaging Experience Enhancement Noncontroversial enhancements Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". and removed Working as Intended The behavior described is the intended behavior; this is not a bug labels Feb 13, 2019
@DanielRosenwasser
Copy link
Member

In isRelatedTo, it should be possible to do a secondary check in the presence of a literal type to see if the base primitive type is related to the target. If not, report against the base primitive type.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Feb 13, 2019

Worth noting that that workaround won't work when elaborating from the top of a union, but it's likely good enough.™

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Feb 13, 2019

@getify apologies there, I labelled this issue and then got interrupted while writing a response. Thanks for being patient.

@JoshuaKGoldberg
Copy link
Contributor

🤔 I'm starting to think TypeScript might want to report both the general primitive and narrow literal. Would it be confusing for an intermediate-to-advanced user that it sometimes reports one or the other? Maybe the error for these should be like Type 'primitive' ('literal') ..?

"Type 'string' ('hello') is not assignable to type 'number'."

@DanielRosenwasser
Copy link
Member

I'd have to see an example of where that would be useful - in that case, I'd say it's actually bound to confuse a user more than help. Even if we're trying to build intuition around singleton types existing for new users, I think it is a regression for intermediate-late users who might still struggle with our messages.

Remember that sometimes our error messages are look like this, so helpful information needs to be actionable and help diagnose the problem. There's nothing about the string "hello" that will help a user diagnose a more fundamental incompatibility between string and number.

@getify
Copy link
Author

getify commented Apr 21, 2020

An error message saying "Type 'hello' ..." is confusing to some people like me with only a casual familiarity with TS. I now (after this thread) understand that intentionally, a string literal can be its own narrow type, but I personally find that odd and surprising in its own right. I for one would have very much appreciated both pieces of information (hello and string) in the error message. Same goes for 42 and number being present in an error message, or true and boolean...

...but even more so for any of the non-string primitives, since they still have ' .. ' single quotes around them (.. '42' .. and .. 'true' ..) in the error messages, which look to me like string values. Being reminded they're actually number and boolean literals is helpful.

OTOH, I don't understand at all how having both pieces of information could ever possibly confuse someone, especially those more experienced ("intermediate-late") users. If you know about literal-types, then you know that "hello" is a narrower form of the general string type, so at worst that information in the error message is only slightly redundant.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented May 26, 2020

When singleton types don't appear at the top-level of the target side, we'll now just simplify down to the the base primitive. Thanks @JoshuaKGoldberg!

@DanielRosenwasser DanielRosenwasser added the Fixed A PR has been merged for this issue label May 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Domain: Error Messages The issue relates to error messaging Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Experience Enhancement Noncontroversial enhancements Fixed A PR has been merged for this issue Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants