Home > database >  get union type with `keyof typeof`
get union type with `keyof typeof`

Time:06-11

How can I get the union or enum type from a typeof type?

Example

const myConfs: { [k: string]: (myArg: { name: string }) => string } = {
  'Hello': ({ name }) => `World from ${name}`,
  'Goodbye': ({ name }) => `World from ${name}`,
};
type MyKeys = keyof typeof myConfs;


// I want this to trow an error
const key: MyKeys = 'hello';

I have tried just removing the type definition of myConfs and that works, but that breaks the type definement of the callback argument within the value field on myConfs.

CodePudding user response:

There are multiple ways of solving this. You are setting your keys to be any string. Use mapped type to limit it to what your set needs to be:

const keys = <const>["Hello", "Goodbye"];

type MyConfs = {
  [K in typeof keys[number]]: (myArg: { name: K }) => string;
};

const myConfs: MyConfs = {
  Hello: ({ name }) => `World from ${name}`,
  Goodbye: ({ name }) => `World from ${name}`
};

// I want this to trow an error
const key: keyof MyConfs = "hello";

CodePudding user response:

I would suggest using a factory function. This let's you solve your problem and avoids code duplication.

function createConfs<T extends { [k: string]: (myArg: { name: string }) => string }>(confs: T) : T{
    return confs
}

const myConfs = createConfs({
  'Hello': ({ name }) => `World from ${name}`,
  'Goodbye': ({ name }) => `World from ${name}`,
})

type MyKeys = keyof typeof myConfs;

const key: MyKeys = 'hello';
// Type '"hello"' is not assignable to type '"Hello" | "Goodbye"'. Did you mean '"Hello"'?(2820)

Playground

  • Related