简体   繁体   English

有没有办法根据对象键在 TypeScript 上动态生成枚举?

[英]Is there a way to dynamically generate enums on TypeScript based on Object Keys?

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.我正在定义一个对象,我想根据它的键动态生成枚举,所以我得到了 IDE 建议并且不要调用错误的键。

const appRoutes = {
   Login,
   Auth,
   NotFound
} 

enum AppRoutes = {[Key in keyof appRoutes]: [keyof appRoutes]}

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:您可以使用keyof typeof appRoutes获得所有键的联合,这将具有您想要的类型安全效果:

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. Typescript 不提供从字符串联合自动创建此类对象的方法。 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;

I use this workaround to convert the keys to a const key -> key object:我使用此解决方法将键转换为 const key -> key 对象:

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";
// }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM