The TypeScript code below has errors about using a string index with an enum in some cases, but not in others. Also, in some environments, the code with "errors" runs anyway.
enum LMSRole {
AccountAdmin = 'Account Admin',
SupportConsultant = 'Support Consultant',
StudentEnrollment = 'StudentEnrollment',
TeacherEnrollment = 'TeacherEnrollment'
}
console.log(LMSRole.SupportConsultant) /* "Support Consultant" - OK */
// these role strings would be read from input
const roles: String[] = ['AccountAdmin', 'SupportConsultant']
console.log(roles.map(r => LMSRole[r]))
/* Error given, yet runs on (http://typescriptlang.org/play)...
* Type 'String' cannot be used as an index type. */
console.log(LMSRole['SupportConsultant']) /* "Support Consultant" - OK */
/* In this example, a type of 'String' is used as an index,
* but there's no error. Why? */
See this in action at typescriptlang.org's Playground.
What I don't understand is why in the map function, I get the error about using the string index. However, using a string directly to get a single value from the enum works without error.
I also don't understand why the Playground reports an error, but it runs anyway. On my own computer, if I try to run it, it will fail before anything is executed.
UPDATE — When I first wrote this question, I didn't explicitly state that I want to use this enum with strings read from input. (Say, from a text file or stream.) I thought the line beginning const roles would express that intention, but I guess it wasn't clear. I've added a comment to the code to clarify. Would that fact prevent the use of suggested code like typing the array Array<keyof typeof LMSRole> or forcing TS to treat the array as const?
stringnotStringfirst of all (primitives not objects) see: What is the difference between types String and string?. But actually what you want is forrolesto be an array of keys ofLMSRole, soconst roles: Array<keyof typeof LMSRole> = ['AccountAdmin', 'SupportConsultant']Array<keyof typeof LMSRole>work with that?as constsolution in the answer as it pushes type errors to the point of enum access where you will want to implement an implicit guard which will both avoid typescript errors and ensure error catching at runtime.