Skip to content

iterating an enum is now an error #33123

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

Closed
gpra opened this issue Aug 28, 2019 · 6 comments
Closed

iterating an enum is now an error #33123

gpra opened this issue Aug 28, 2019 · 6 comments
Assignees
Labels
Rescheduled This issue was previously scheduled to an earlier milestone Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@gpra
Copy link

gpra commented Aug 28, 2019

Iterating a string enum in strict mode is not allowed since 3.6.2. Is this a breaking change or a bug?

Sample code:

// sample.ts
// compile with: `tsc --strict sample.ts`
enum DAYS { Monday = 'monday', Tuesday = 'tuesday' }

for (const a in DAYS) {
  const x = DAYS[a];  // <- This is now an error
  console.log(x);
}

tsc --strict sample.ts

TSC 3.5.2: Compiles OK

TSC 3.6.2: reports an error:
error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof DAYS'.

@chermme
Copy link

chermme commented Aug 29, 2019

I confirm, it happens to me as well, I couldn't find any way to overcome this problem.

@sandersn sandersn added the Needs Investigation This issue needs a team member to investigate its status. label Aug 29, 2019
@sandersn sandersn added this to the TypeScript 3.7.0 milestone Aug 29, 2019
@jochenonline
Copy link

jochenonline commented Dec 15, 2019

A workaround until the problem is solved is to use an interim object:

let _DAYS: {[propName: string]: string} = <any> DAYS;

@bytenik
Copy link

bytenik commented Jan 25, 2020

Still having this issue.

@bdunks
Copy link

bdunks commented Jun 17, 2020

As another alternative that feels a bit less like a work-around (at least to me) is to use type assertions after creating a new type based on the enum keys.

enum DAYS {
  Monday = 'monday',
  Tuesday = 'tuesday',
}

type DaysKeys = keyof typeof DAYS; //<- Equivalent to type DaysKeys = 'Monday' | 'Tuesday'; 
  
for (const a in DAYS) {
  const x = DAYS[a as DaysKeys]; //<- assert type
  console.log(x);
}

@RyanCavanaugh RyanCavanaugh added the Rescheduled This issue was previously scheduled to an earlier milestone label Aug 31, 2020
@rbuckton
Copy link
Contributor

This was due to #31687 and was an intentional change:

Types representing object literals or modules have inferable index signatures because their exact set of properties is known. This PR implements the same behavior for types representing enum objects since these also have exact and close ended sets of properties.

  • The enum object type of an enum with at least one numerically valued member has an implicit string index signature of type string | X, where X is a union of the types of all numerically valued members, and an implicit numeric index signature of type string.

  • The enum object type of an enum with only string valued members has an implicit string index signature of type string and no implicit numeric index signature.

In the above, X reflects the reverse mapping from strings to numeric enum values included in the generated code that initializes the enum object.

Essentially, enum declarations became stricter since the domain of possible keys is a closed set, but the type provided by for..in is just string, which is not specific enough.

@rbuckton
Copy link
Contributor

The workaround is as @bdunks describes:

enum DAYS {
  Monday = 'monday',
  Tuesday = 'tuesday',
}

for (const a in DAYS) {
  const x = DAYS[a as keyof typeof DAYS];
  console.log(x);
}

@rbuckton rbuckton added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Nov 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Rescheduled This issue was previously scheduled to an earlier milestone Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

8 participants