Closed
Description
Bug Report
🔎 Search Terms
Mapped index with enum index
typescript dynamic generic type enum loop
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about distributive object types
⏯ Playground Link
Playground link with relevant code
💻 Code
//Enum
enum StateProperty {
ABS = "ABS",
DEF = "DEF",
Object = "OBJECT"
}
//Type definition for mapping type
type StatePropertyMapping = {
[property in StateProperty]: UsesAType<any>
}
//Actual type mappings
class TypeMappingClass implements StatePropertyMapping {
[StateProperty.ABS]: UsesAType<boolean>;
[StateProperty.DEF]: UsesAType<number>;
[StateProperty.Object]: UsesAType<{a: number; b: boolean}>;
}
class UsesAType<T>{
public defaultValue: T;
}
class UsesTypeMapping<Key extends StateProperty>{
public key: Key;
public value: TypeMappingClass[Key]['defaultValue']; //This is a separate class that wants to know the type mapping for 'Key'
public takesValue = (v: TypeMappingClass[Key]['defaultValue']) => {return v};
}
//Definition 1
// Using this definition gives an error that 'StateProperty can't be used to index MapUsesTypeMapping'
// type MapsUsesTypeMapping = {
// [key in StateProperty]: UsesTypeMapping<key>
// }[StateProperty]
//Definition 2
//Using this definition gives an error that 'parameter to takesValue is not assignable to never'
type MapsUsesTypeMapping = {
[key in StateProperty]: UsesTypeMapping<key>
}
class WithMapAsMember {
public mapMember: MapsUsesTypeMapping;
constructor(mapMember: MapsUsesTypeMapping) {
this.mapMember = mapMember;
}
public this_fails(){
for(let s in StateProperty){
//Error occurs here
this.mapMember[s as StateProperty].takesValue(this.mapMember[s as StateProperty].value)
}
}
public this_works_with_casting(){
for(let s in StateProperty){
let t = s as StateProperty;
//This works with definition 2 only
(<UsesTypeMapping<typeof t>>this.mapMember[t]).takesValue(this.mapMember[t].value)
}
}
}
🙁 Actual behavior
If I try to setup the mapping using an enum, the compiler is unable to infer the type mapping based of the union type when the value is generated at runtime (i.e. in a loop)
🙂 Expected behavior
I expect that the compiler will be able to infer the type that takesValue accepts when mapMember is indexed using a specific state property, similar to how it is described in this issue: #47109