-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Element type of enum should include enum type #55713
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
Comments
Duplicate of #39627. Simpler repro: enum E {A};
for (const key in E) {
let __ = E[key];
// ^?
console.log(typeof __);
} |
Isn’t this just another manifestation of #10530 or am I misreading the issue? Because according to the OP narrowing |
No, because Edit: well, that’s the answer to
and I guess #10530 does stand in the way to making the original work as intended, but I feel like the primary thing going on is the lack of |
I had a good look at that issue before filing this one—apologies for not citing it—but it appeared to be:
…but upon more careful re-reading I see that amongst those other topics it does indeed discuss the question of the element type of numeric-only enums:
Thanks for pointing to that issue, though I see that it is a bit underspecified: the actual reported issue has been fixed. You are correct in observing that part of my problem is due to the issue reported in many of the bugs closed as duplicates of that one, however.
Agreed, and I have updated the title and description of this one accordingly. |
Yep, I’m aware. Even the maintainers tend to dupe to that one, and I’ve voiced my opinion a few times that I wish there was a more accurate dupe, as the |
This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
🔎 Search Terms
enum element type computed index reverse lookup
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play?#code/KYOwrgtgBAolDeBBAvgbgFDoGYHsBOUAFAMY4gDOALlANbACeUAliLAJQLpTdQA2w1APqCoAXlgBtOvQC6GHlAD0i7gD0A-Fx6kKOfgDpeOAOaFK9AA7AcWKMLYZkQA
💻 Code
🙁 Actual behaviour
The (
tsc
-reported) type of__
isstring
🙂 Expected behaviour
The (
tsc
-reported) type of__
should be 'A' | E, or at least
string | number`.Additional information about the issue
This issue singles out one of several different problems discussed in #39627.
See also #39627 and #42457, which discuss iterating over
enum
entries in different contexts.Background
We are migrating a (Closure type system) JavaScript library to TypeScript.
In times past our code looked like:
In preparation for the migration to TypeScript, and since the
E_x
properties are used as an enum, we first converted them to an@enum
but included code to maintain backwards compatibility as follows:My initial naïve conversion to TypeScript:
helpfully elicited the (correct and useful) error "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'C'. No index signature with a parameter of type 'string' was found on type 'C'."
Since this is only for backwards compatibility with legacy client code I don't wish to add an index signature to type
C
(new client code written in TypeScript should use the enum directly), so instead I attempted to simply coerce the type ofthis
to a allow the assignments:This produces the error message "Type 'string' is not assignable to type 'number'.(2322)", which is useful, insofar as it (eventually) alerted me tho the change of semantics of
E
, which now also includes the reverse-lookup table, but it is incorrect because the actual type ofE[key]
should be something like(keyof typeof E) | E
, or at leaststring | E
(or failing that even juststring | number
)—but definitely not juststring
.This inspecificity of the type of an enum when using it for reverse lookups has previously been the subject of issues #38806 and #50933, but those issues do not highlight the fact that the type only supports reverse lookups.
Surprisingly, adding a guard clause is not sufficient to satisfy the type checker:
This still complains that
E[key]
is a string even though string has been explicitly eliminated. [Update: this turns out to be due to #10530—or rather any of its many supposed duplicates, since the specific original example reported there has been fixed.]Adding a temporary variable however does work:
because
tsc
'correctly' deduces thatvalue
has typenever
.It is not clear why it does not make the same deduction aboutE[key]
in the previous snippet.The text was updated successfully, but these errors were encountered: