-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Index signature error for mapped type when keyed on declare enum
#31771
Comments
Just to be clear, in my actual use case, the enum is declared in a declare module "mylib" {
enum E2 { ONE, TWO, THREE }
} In my code, I |
This is technically working as intended, but a bit convoluted. In an Now, the thing that maybe isn't right here is the behavior of a numeric enum type as the key type in a mapped type, such as |
I think I'm learning that ambient enum declarations are pretty weird. After your comment, I went and poked around in the playground and found a couple of edge cases that also seem "a bit convoluted". declare enum E1 { ONE, TWO, THREE = true } // "In ambient enum declarations member initializer must be constant expression." (isn't `true` constant?)
declare enum E2 { ONE, TWO, THREE = 'x' }
type B2 = { [k in E2]?: string; } // Type 'E2' is not assignable to type 'string | number | symbol'.
let e2: E2 = E2.ONE;
e2 = E2.THREE; // no error
e2 = 'x'; // Type '"x"' is not assignable to type 'E2'. I was surprised to find that you can include value assignments in the ambient declaration in the first place, because I can't think of another example where the description of the shape of a module includes information about runtime values -- it seems like an intrusion on the type space. Is there a different syntax to use to say that this module exports an enum-like object, and I don't know or care about the type of its values? I guess you'd have to at least be able to say that they're constrained to |
I agree the first error in your example could have a better error message. The second error is fixed by #31784. The third error is intended. String literal types are not considered assignable to string valued enum literal types (but the reverse is allowed).
Yeah. The weirdness mostly comes from the fact that, for reasons of backward compatibility, we have two subtly different flavors of enums, as described in #15486. In order for enum E1 { ONE, TWO, THREE }
declare enum E2 { ONE = 0, TWO = 1, THREE = 2 } The subtlety here is that the absence of an initializer generally implies auto-numbering, except in an ambient non-const enum where it implies a computed value.
Except for the odd case of computed enum members (which, again, are there mostly for backwards compatibility reasons), enum members are just labelled literal constants and the compiler definitely needs to know their values in order to use them for control flow analysis, etc. This holds whether or not the enums are declared ambiently.
You could just export an object literal expression. |
TypeScript Version: 3.2.4 plus whatever's on the Playground
Search Terms: enum mapped index signature
Code
Expected behavior: Indexed access to a mapped type should be possible as long as we guarantee ahead of time that the index value is of the correct key type.
Actual behavior: Compiler allows indexed access only if it knows that the enum value is a literal.
Playground Link: Here, make sure to turn on
noImplicitAny
Related Issues: #13042 appears to work but only addresses locally-defined enums
I'm trying to key on enum-values from a library I depend on so I'm stuck using ambient declarations. If this is "by design", or allowing enum values whose runtime contents cannot be determined at compile time is too difficult to support, I'd welcome suggestions for an alternate approach.
The text was updated successfully, but these errors were encountered: