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

enum with bigger integer than available is allowed #8020

Closed
donaldpipowitch opened this issue Apr 12, 2016 · 12 comments
Closed

enum with bigger integer than available is allowed #8020

donaldpipowitch opened this issue Apr 12, 2016 · 12 comments
Labels
Duplicate An existing issue was already created

Comments

@donaldpipowitch
Copy link
Contributor

Code

export enum ModelType {
  Repositories,
  Gists
};

function test(modelType: ModelType) {

}

test(2);

Example
Expected behavior:

Throw error, because 2 shouldn't be available in ModelType.

Actual behavior:

No error is thrown.

@RyanCavanaugh
Copy link
Member

We don't distinguish between flag and non-flag enums, so a number that is above any given enum member isn't necessarily invalid. For example

enum Flags {
  Neat = 1,
  Cool = 2,
  Great = 4
}
// like saying Neat | Cool | Great
var x: Flags = 7;

@donaldpipowitch
Copy link
Contributor Author

Can I opt-out from that? This is unexpected for me and for my use cases not useful. Or can I use strings as values and reference them like ModelType.Gists (instead of using 'foo' | 'bar' and use strings directly).

@RyanCavanaugh
Copy link
Member

There's no opt-out setting. Can you show an example of what you mean about using strings?

@donaldpipowitch
Copy link
Contributor Author

Say the function test only accepts 'foo' or 'bar' as possible types. I could do it that way:

type Value = 'foo' | 'bar';

function test(value: Value) {

}

test('foo');

However I need to pass 'foo'``directly which can be troublesome for refactoring. I'd rather pass something likeValue.fooas a reference to'foo'` (which also reads nicer in my opinion). Is this possible somehow? The best thing I can come up with is this beast:

type Value = 'foo' | 'bar';

type IValueMap = {
  foo: 'foo',
  bar: 'bar'
};

const ValueMap: IValueMap = {
  foo: 'foo',
  bar: 'bar'
};

function test(value: Value) {

}

test(ValueMap.foo);

(You need IValueMap or you'll get Argument of type 'string' is not assignable to to parameter of type '"foo" | "bar"'.)

Going back to my original example I probably would like something like enum, but as a fixed dictionary (which would compile to the same output as my last example with IValueMap):

export dictionary ModelType {
  Repositories: 'repos',
  Gists: 'gists
};

function test(modelType: ModelType) {

}

test(ModelType.Repositories);
test('repos'); // this would work, too

Conclusion

Maybe I should rather write a dictionary proposal which works exactly like this?:

export dictionary ModelType {
  Repositories: 'repos',
  Gists: 'gists'
};

function test(modelType: ModelType.Value) {

}

compiles to

type ModelTypeValue = 'repos' | 'gists';

type IModelType = {
  Repositories: 'repos',
  Gists: 'gists'
};

const ModelType: IModelType = {
  Repositories: 'repos',
  Gists: 'gists'
};

export ModelType;

function test(modelType: ModelTypeValue) {

}

@Elephant-Vessel
Copy link

I also think that the flag-behavior of enums would have been nice to have separated into another keyword like flag since that behavior is really different from the common usage of enums as a a simple set of named constant values.

However I'm unsure and curious about what you want to achieve here, why don't you just reference the enum value on the ModelType directly like test(ModelType.Gists) instead of sending in wild integers if you want more safety and improving refactoring?

@donaldpipowitch
Copy link
Contributor Author

However I'm unsure and curious about what you want to achieve here, why don't you just reference the enum value on the ModelType directly like test(ModelType.Gists) instead of sending in wild integers if you want more safety and improving refactoring?

Oh, I don't want the send integers directly. I do use the reference like ModelType.Gists. I found that by accident and thought it was a bug.

@Elephant-Vessel
Copy link

@donaldpipowitch So that stuff about strings, how would that improve the language?

@donaldpipowitch
Copy link
Contributor Author

You could reference the string instead of passing it directly. Or what do you mean?

@Elephant-Vessel
Copy link

I mean, this is still about how to work with enums right? Or have this issue changed to be about the general possibility to reference values in string literal types like we do with enums?

@donaldpipowitch
Copy link
Contributor Author

I mean, this is still about how to work with enums right?

Yeah. I'd definitely like to see an enum alternative to not allow things like that:

export enum ModelType {
  Repositories,
  Gists
};

function test(modelType: ModelType) {

}

test(2);

Or have this issue changed to be about the general possibility to reference values in string literal types like we do with enums?

That would probably a second issue. However this could both be solved with the same feature, if I could define an enum with limited custom values (which could be just 0 and 1 or 'gists' and 'repos').

@mhegazy
Copy link
Contributor

mhegazy commented Apr 13, 2016

The issue referenced in OP is by design as noted in #8020 (comment)

The rest of the discussion is about non-number based enums, and this is already tracked by #1206.

@mhegazy mhegazy closed this as completed Apr 13, 2016
@mhegazy mhegazy added the Duplicate An existing issue was already created label Apr 13, 2016
@andremarcondesteixeira
Copy link

andremarcondesteixeira commented Jul 16, 2017

maybe, you guys could use:

export class MyClass {
    public teste(bla : foo) : void {
        console.log(bla);
    }

    public teste2() : void {
        this.teste(weekDay.Sábado);
    }
}

enum weekDay {
    Domingo,
    Segunda,
    Terça,
    Quarta,
    Quinta,
    Sexta,
    Sábado
}

export type foo = weekDay.Sábado | weekDay.Domingo;

It will throw the desired errors, and will preserve refactoring capabilities.

@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
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants