29

I'm defining an object and I want to dynamically generate enum based on its keys, so I get IDE suggestions and do not call wrong keys.

const appRoutes = {
   Login,
   Auth,
   NotFound
} 

enum AppRoutes = {[Key in keyof appRoutes]: [keyof appRoutes]}
Jeroen Heier
  • 3,520
  • 15
  • 31
  • 32

3 Answers3

27

You can't build an actual enum from the object keys.

You can get a union of all keys with just keyof typeof appRoutes and that will have the type safe effect you want:

type AppRoutes = keyof typeof appRoutes

let ok: AppRoutes = "Auth";
let err: AppRoutes = "Authh";

An enum is not just a type though, it's also a runtime object that contains the keys and values of the enum. Typescript does not offer a way to automatically create such an object from a string union. We can however create a type that will ensure that the keys of an object and the members of the union stay in sync and we get a compiler error if t hey are not in sync:

type AppRoutes = keyof typeof appRoutes
const AppRoutes: { [P in AppRoutes]: P } = {
    Auth : "Auth",
    Login: "Login",
    NotFound: "NotFound" // error if we forgot one 
    // NotFound2: "NotFound2" // err
}
let ok: AppRoutes = AppRoutes.Auth;
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
4

I use this workaround to convert the keys to a const key -> key object:

const { Login, Auth, NotFound } = {} as any
const appRoutes = {
  Login,
  Auth,
  NotFound
}

const AppRoutes = (() => ({
 ...Object.keys(appRoutes)
   .filter(k => isNaN(Number(k)))
   .reduce((acc, cur) => ({
     ...acc,
     [cur]: cur,
   }), {}),
} as  {
 [k in keyof typeof appRoutes]: k
}))()

console.info(AppRoutes)
// AppRoutes: {
//   Login: "Login";
//   Auth: "Auth";
//   NotFound: "NotFound";
// }
Huan
  • 2,876
  • 3
  • 30
  • 49
0

Anyways enum in typescript get converted to object, so I think, best is to create an object dynamically

 type A = keyof typeof ImagePresetDetails;
 const ImagePresetsObject:Record<A,A> = {}; // use this as enum
 for (const key in ImagePresetDetails) {
     ImagePresetsObject[key] = key;
 }
Akshay Vijay Jain
  • 13,461
  • 8
  • 60
  • 73