Skip to content

Comparability of Enum values #10631

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

Closed
m1gu3l opened this issue Aug 31, 2016 · 7 comments
Closed

Comparability of Enum values #10631

m1gu3l opened this issue Aug 31, 2016 · 7 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@m1gu3l
Copy link
Contributor

m1gu3l commented Aug 31, 2016

TypeScript Version: 2.0.2 Release Candidate

Code

enum Place {
    Bottom,
    Left,
    Right,
    Top
}

let p: Place = Place.Left;
console.log(p === Place.Left);
console.log(p === Place.Right);

Expected behavior:
true
false

Actual behavior:
error TS2365: Operator '===' cannot be applied to types 'Place.Left' and 'Place.Right'.

@m1gu3l
Copy link
Contributor Author

m1gu3l commented Aug 31, 2016

#10119 and #10120 might be related

@ahejlsberg
Copy link
Member

This is working as intended. The compiler performs control flow analysis and knows that p has the actual value Place.Left where you're performing the === operations, and it is calling out that it makes no sense to compare a value that is known to be Place.Left to a value that is known to be Place.Right. It's effectively like writing Place.Left === Place.Right or 1 === 2, both of which would also produce errors.

@ahejlsberg ahejlsberg added the Working as Intended The behavior described is the intended behavior; this is not a bug label Aug 31, 2016
@m1gu3l
Copy link
Contributor Author

m1gu3l commented Aug 31, 2016

Oh, thanks for clarifying that. It still feels a bit weird.

It's effectively like writing Place.Left === Place.Right or 1 === 2, both of which would also produce errors.

Well no, it's like writing let p = 0 and then checking p === 1, which would produce false.

@m1gu3l m1gu3l closed this as completed Aug 31, 2016
@ahejlsberg
Copy link
Member

ahejlsberg commented Aug 31, 2016

The thing that triggers the stricter behavior is that the type of the variable is one with a finite set of choices (i.e. a union type or an enum type). For example, the following is also an error

let p: 0 | 1 = 0;
console.log(p === 1);  // Error, comparing 0 to 1

@m1gu3l
Copy link
Contributor Author

m1gu3l commented Aug 31, 2016

I understand.
It seems to be an overkill though. Sometimes developer might want to do check like that. And what about generated code?

@RyanCavanaugh
Copy link
Member

You can write let p: Place = <Place>Place.Left; if you want to "erase" the known value of the variable.

In reality this check actually found a lot of bugs when it was created. People would check for an enum value and return, then check for it again (creating an unreachable block), etc.

Generated code should never be in a bad state due to this since the generator itself can know when it would emit unreachable blocks. And usually you wouldn't typecheck generated code anyway (since it ought to be correct).

@m1gu3l
Copy link
Contributor Author

m1gu3l commented Aug 31, 2016

In ideal world there would be a flag to disable this globally, but I've noted my position is in the minority.

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants