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

Type narrowing with non-literal const enums #19321

Closed
jcludwig opened this issue Oct 19, 2017 · 4 comments
Closed

Type narrowing with non-literal const enums #19321

jcludwig opened this issue Oct 19, 2017 · 4 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@jcludwig
Copy link

jcludwig commented Oct 19, 2017

Type narrowing does not appear to cover the cases where a const enum member's value is not a literal.

const enum ConstEnum {
    foo = 2 | 1,
}

function f(e: ConstEnum): number {
    switch (e) {
        case ConstEnum.foo:
            return 0;
        default:
            assertNever(e);
    }
}

export function assertNever(x: never): never {
    throw new Error('Expected never to have value ' + x);
}

This code will result in the following error: Argument of type 'ConstEnum' is not assignable to parameter of type 'never'. However, the switch should be covering all cases, and therefore I would expect the type of e to be never in the default case. Changing the value of foo to a literal by removing arithmetic results in the expected behavior (no error). It looks like the compiler is properly doing the arithmetic at compile-time to compute 2 | 1 = 3.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 19, 2017

Enums can be used to mean a set of literal values, or a set of flags. for flags doing an exhaustive check is not correct. the compiler uses the existence of an intializer + expression as an indication that this is a flag enum, and disables narrowing. enabling narrowing on non-literal enums would be a breaking change.

@mhegazy mhegazy added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Oct 19, 2017
@jcludwig
Copy link
Author

Ah I see. I agree with you with respect to type narrowing being suspicious when you have a flags enum. Unfortunately it seems like using the existence of an expression initializer will produce both false positives (just because I use an expression does not indicate I necessary intend to combine the values) and false negatives (some people specify the flags values as literals). Did this decision take place on GitHub, do you happen to have a link to the PR?

@mhegazy
Copy link
Contributor

mhegazy commented Oct 19, 2017

#9407

@mhegazy
Copy link
Contributor

mhegazy commented Nov 6, 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 Nov 6, 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
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

2 participants