Search code examples
typescript

Replacing a type with a type map in typescript


I have enums in typescript that are implemented with types and objects. I want a generic method that can deal with them in a typesafe way.

type MyEnum = 1 | 2 ; 
const MyEnum = { 
    AAA: 1 as MyEnum, 
    BBB: 2 as MyEnum,
}

type MyEnum2 = 'a' | 'b' ; 
const MyEnum2 = { 
    a: 'a' as MyEnum2, 
    b: 'b' as MyEnum2,
}

Doing so explicitly works well:

function getA<E extends 'myenum', B extends keyof typeof MyEnum>(e: E, key: B): void;
function getA<E extends 'myenum2', B extends keyof typeof MyEnum2>(e: E, key: B): void;
function getA<E, B>(e: E, key: B): void {
    console.log(e, key);
}
getA("myenum", "AAA");

When using a type map, it does not work:

type EnumTypes = {
  myenum: MyEnum;
  myenum2: MyEnum2;
}

function getB<E extends keyof EnumTypes, B extends keyof EnumTypes[E]>(e: E, key: B) {
    console.log(e, key);
}
get4("myenum", "BBB");

Why is keyof EnumTypes[E] of type "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString" ?


Solution

  • You forgot to set proper types for EnumTypes:

    Playground

    type EnumTypes = {
      myenum: typeof MyEnum;
      myenum2: typeof MyEnum2;
    }