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

request: optionally disable enum/number implicit conversion #17734

Closed
Spongman opened this issue Aug 11, 2017 · 13 comments
Closed

request: optionally disable enum/number implicit conversion #17734

Spongman opened this issue Aug 11, 2017 · 13 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@Spongman
Copy link

Spongman commented Aug 11, 2017

now that we have union types, can we please have an option to disable the enum/number implicit casts?

I'd really like the following to give me an error:

enum Shape { Circle, Square, Pentagon, Pyramid }
var f = Math.sin(Shape.Square)
@mhegazy
Copy link
Contributor

mhegazy commented Aug 17, 2017

This breaks flag enums, where bit operations are allowed.

@mhegazy mhegazy added the Working as Intended The behavior described is the intended behavior; this is not a bug label Aug 17, 2017
@Spongman
Copy link
Author

Spongman commented Aug 24, 2017

actually, you could still allow boolean operations on enums. i'm just requesting that they not be implicitly converted to/from numbers (except maybe from zero).

we already have a way of representing collections of constant integers in the language (ie. classes with public static readonly fields). allowing enums to be implicitly converted to/from number just duplicates this and doesn't provide the most useful purpose that enumerations could have - type safety.

@mhegazy
Copy link
Contributor

mhegazy commented Aug 24, 2017

if we were to do it allover again, i would have flags and enums be separate entities. but that is not possible now. any changes to the enums now would lead to a massive breaking change. The TS code base for instance relies on flags extensively, and i am sure we are not unique in this regard.

@Spongman
Copy link
Author

yeah, like i said. can we have an option to do this?

@mhegazy
Copy link
Contributor

mhegazy commented Aug 24, 2017

we have a limited budget of options, each option adds maintenance costs on the team and learning cost on users.
Moreover we have no other alternatives for flag enums, and we have no plans on adding a new kind of enums.

@Spongman
Copy link
Author

well, if what you want is a collection of integer values, then the language already has a non-type-safe alternative: classes. eg:

class MyConsts {
    static readonly Flag1 = (1<<0);
    static readonly Flag2 = (1<<1);
    // etc...
}

this performs almost as well as an enum and it's already non-type-safe. so, basically, what you have today is two almost identical ways of doing exactly the same thing.

as far as i know, since the beginning, Anders has always sold typescript on the grounds that it's a typesafe javascript, useful for building large projects with large teams. adding type safety to enums would certainly fit this goal. i'm pretty sure it would help fix more bugs than would simply providing some syntactic sugar for collections of consts.

@Spongman
Copy link
Author

on a related note, i just discovered that you can't have an enum as an object index:

enum Foos {
   Bar = 0,
   Goo = 1,
}

type MAP = { [key: Foos]: number };

results in An index signature parameter type must be 'string' or 'number'

so which is it? is enum a convenient alias for collections of consts numbers, or a typesafe enumeration of discrete elements? 'cos right now it seems inconsistent.

@mhegazy
Copy link
Contributor

mhegazy commented Aug 31, 2017

see #2049

@Spongman
Copy link
Author

Spongman commented Sep 2, 2017

hah, so i wrote a tslint rule to do this, and after running on the tsc project i see now why you wouldn't want to do this.

here's my favorite:

namespace ts.formatting {
    const enum Constants {
        Unknown = -1
    }
}

that's an enumeration of all the values that a variable of type Constants can take. really?

why not just this? :

namespace ts.formatting.Constants {
    const Unknown = -1;
}

same for CharacterCodes, ExitStatus & RulesPosition.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 5, 2017

this one specifically is wrong, but the general rule stands. look at things like NodeFlags.

@Spongman
Copy link
Author

Spongman commented Sep 6, 2017

absolutely. and nowhere[*] is a variable of type NodeFlags used in a (non-comma) binary or conditional expression with a number-typed expression, or initialized (as a parameter, property or variable) as a number-typed expression, or returned from a number-typed function.

[*] except for a few times where it's compared to 0, which could (arguably should?) be fixed to NodeFlags.None.

indeed, here's a complete diff of changes that would satisfy this: tsc.patch.txt

(also, this: return pos += 2, token = SyntaxKind.ExclamationEqualsToken; ?!)

@michael-s-crouch
Copy link

I would also like the ability to check for this. I defined enums entirely so that I could use static typechecking to make sure that they were being used correctly; right now, typescript isn't capturing that.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 25, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed Sep 25, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 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