-
Notifications
You must be signed in to change notification settings - Fork 13.3k
TypeScript "forgets" enum in mapped type key #52251
Copy link
Copy link
Closed
Labels
Working as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug
Description
Bug Report
Enum values can be used on both sides of a mapped type (key/value). For values, things work great! For keys, the enum is "forgotten" and replaced with its integral value. This can cause problem for further type logic.
🔎 Search Terms
Enum, Mapped Type
🕗 Version & Regression Information
Replicated in playground in 3.3.3333, 4.9.4, and nightly.
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about enums and mapped types
- I was unable to test this on prior versions because playground only goes back to 3.3.3333
⏯ Playground Link
💻 Code
enum MyEnum {
MyEnumValue
};
type EnumOnBothMapSides = {[MyEnum.MyEnumValue]: MyEnum.MyEnumValue};
/*
EnumOnBothMapSides inferred as:
type EnumOnBothMapSides = {
0: MyEnum.MyEnumValue;
}
Notice that the enum-ness has been lost in the key
*/
type EnumValueType = typeof MyEnum[MyEnum.MyEnumValue];
/*
EnumValueType inferred as:
type EnumValueType = string
It would be nice if this were "MyEnumValue", but that's more of a feature request than a bug.
Nonetheless, we now know that indexing into MyEnum with MyEnumValue produces a string.
Let's specify that:
*/
type MyEnumIndex = {[MyEnum.MyEnumValue]: string};
/*
MyEnumIndex inferred as:
type MyEnumIndex = {
0: string;
}
This replicates the "forgetfulenss" seen above.
*/
const myEnumIndex: MyEnumIndex = MyEnum;
/*
Error:
Property '[MyEnum.MyEnumValue]' is missing in type 'typeof MyEnum' but required in type 'MyEnumIndex'.(2741)
Earlier, however, TypeScript was quite explicit that "typeof MyEnum[MyEnum.MyEnumValue]" is a string.
*/🙁 Actual behavior
myEnumIndex doesn't typecheck.
🙂 Expected behavior
myEnumIndex typechecks, as its type describes a demonstrable behavior of the enum type. This should be, in effect, a widening/covariant conversion which TS is generally ok with.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Working as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug