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

x != y marked as always true when it is not #36534

Closed
DominicKramer opened this issue Jan 30, 2020 · 5 comments
Closed

x != y marked as always true when it is not #36534

DominicKramer opened this issue Jan 30, 2020 · 5 comments
Labels
Won't Fix The severity and priority of this issue do not warrant the time or complexity needed to fix it

Comments

@DominicKramer
Copy link

Search Terms:
!=, implicit conversion

Code

const x = 0;
const y = '0';

if (x != y) {
  console.log('In if block');
} else {
  console.log('In else block');
}

Expected behavior:
The code should compile successfully. Since != uses implicit conversion it is possible for 'x != y' to be false even if x is a number and y is a string. For example 0 != '0' is false).

Note that when the javascript file generated by tsc in the above code is run, the else block is hit as expected.

Actual behavior:
The code has the compilation error:

error TS2367: This condition will always return 'true' since the types 'number' and 'string' have no overlap.

5 if (x != y) {
      ~~~~~~

Playground Link:

http://www.typescriptlang.org/play/?ts=3.8.0-dev.20200128#code/FAYw9gdgzgLgBADzgXjgBgNykrOBPFOAcjSK2AEsAzOACiQEJU8BKOAb2DjnGjABsApgDp+YAOa0iASQhxqcAEZiQAayIssAXziD+UQRy48cAkWMky5eg0pXrNwLcCA

Related Issues:

No

@znrm
Copy link

znrm commented Jan 30, 2020

This is intended as per the TS spec; == and === are both handled in the same way.

You can easily opt into the behavior you expect by casting either side of the comparison to any.

if (x as any != y) { }

@shicks
Copy link
Contributor

shicks commented Jan 30, 2020

That spec doesn't gel with the current behavior, at least for some of the later operators (&& and ||). For instance, && says that the return type is the same as the second argument, and || that it's the union - and then each gives a seemingly nonsensical table. But in actuality, TS does the right thing and unions the truthy or falsy projections of the left-hand type with the right-hand type.

To the original point, at the very least the error message is misleading.

@RyanCavanaugh RyanCavanaugh added the Won't Fix The severity and priority of this issue do not warrant the time or complexity needed to fix it label Jan 31, 2020
@RyanCavanaugh
Copy link
Member

This error message is correct the other 99.5% of the time and it'd be confusing to tack on a "... unless there's an implicit coercion which you shouldn't be doing anyway" clause to the message just to make it Technically Correct

@jcalz
Copy link
Contributor

jcalz commented Jan 31, 2020

I feel like "it will always be true" or "it will always be false" is kind of beside the point, though. The real problem is "you shouldn't be comparing these things because the types aren't compatible". The implicit coercion is the problem, not the fact that one of the clauses is potentially unreachable. I can write if (3 !== 3) { } and there's no complaint.

That said this is probably a duplicate of #26592

@PixnBits
Copy link

This error message is correct the other 99.5% of the time and it'd be confusing to tack on a "... unless there's an implicit coercion..." clause to the message just to make it Technically Correct

FWIW trying out TypeScript in a new project I understood the existing message to mean that TypeScript didn't know how JavaScript evaluates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Won't Fix The severity and priority of this issue do not warrant the time or complexity needed to fix it
Projects
None yet
Development

No branches or pull requests

6 participants