简体   繁体   English

如何在 TypeScript 中嵌套枚举?

[英]How to nest enums in TypeScript?

Let's say I have a function like this but with many more possible values for the enum parameter:假设我有一个这样的函数,但 enum 参数有更多可能的值:

enum API{
    userDetails = "/api/user/details",
    userPosts = "/api/user/posts",
    userComments = "/api/user/comments",
    postDetails = "/api/post/details",
    postComments = "/api/post/comments"
    //...
};

function callAPI(endpoint: API/*, some more params*/){
    // some code to deal with the specified endpoint...
}

callAPI(API.userComments);

The above code works fine, but I need to group the many values of the enum into an organized hierarchical structure in order to make things a little more organized... For example, it would be much better if the syntax for calling the API can be callAPI(API.user.comments) instead of callAPI(API.userComments) .上面的代码工作正常,但我需要将枚举的许多值分组到一个有组织的层次结构中,以便使事情更有条理...例如,如果调用 API 的语法可以更好是callAPI(API.user.comments)而不是callAPI(API.userComments)

I tried things like the below attempts but it looks like none were accepted as a valid syntax for typescript.我尝试了以下尝试,但似乎没有一个被接受为打字稿的有效语法。

Attempt 1尝试 1

enum API{
    user = {
        details : "/api/user/details",
        userPorts : "/api/user/posts",
        userComments : "/api/user/comments"
    }
    post = {
        postDetails : "/api/post/details",
        postComments : "/api/post/comments"
    }
}

Attempt 2尝试 2

enum user {
    details = "/api/user/details",
    userPorts = "/api/user/posts",
    userComments = "/api/user/comments"
}
enum post {
    postDetails = "/api/post/details",
    postComments = "/api/post/comments"
}
enum API{
    user,
    post
}

Attempt 3尝试 3

enum user {
    details = "/api/user/details",
    userPorts = "/api/user/posts",
    userComments = "/api/user/comments"
}
enum post {
    postDetails = "/api/post/details",
    postComments = "/api/post/comments"
}
enum API{
    user = user,
    post = post
}

Attempt 4尝试 4

enum user {
    details = "/api/user/details",
    userPorts = "/api/user/posts",
    userComments = "/api/user/comments"
}
enum post {
    postDetails = "/api/post/details",
    postComments = "/api/post/comments"
}
enum API{
    user:user
    post:post
}

My understanding is that it's not possible with enums - right hand side of an enum member can be either nothing, number, string, or another enum value.我的理解是枚举是不可能的 - 枚举成员的右侧可以是空、数字、字符串或另一个枚举值。 See https://www.typescriptlang.org/docs/handbook/enums.html for more details.有关更多详细信息,请参阅https://www.typescriptlang.org/docs/handbook/enums.html

But you can easily achieve what you want with plain objects.但是您可以使用普通对象轻松实现您想要的。

const API = {
  user: {
    details: "/api/user/details",
    posts: "/api/user/posts",
  },
  // ...
};

If you're worried that it might be modified, you can use Object.freeze .如果您担心它可能会被修改,您可以使用Object.freeze

If you need to pass the whole API object to a function via argument then you'll need to define an interface for it too, but otherwise autocomplete and checks should work just fine.如果您需要通过参数将整个 API 对象传递给函数,那么您也需要为它定义一个接口,否则自动完成和检查应该可以正常工作。

-------- edit - - - - 编辑

Adding types in case you find them useful:添加类型以防您发现它们有用:

export type ApiRoutes<TRoute extends string> = { [key in TRoute]: string };

export interface MyApi {
  user: ApiRoutes<"details" | "posts" | "comments">;
  post: ApiRoutes<"details" | "comments">;
}

You could wrap it inside a namespace :你可以将它包装在一个命名空间中

namespace API{
    export enum User {
        details = "/api/user/details",
        posts = "/api/user/posts",
        comments = "/api/user/comments",
    }
    export enum Post {
        details = "/api/post/details",
        comments = "/api/post/comments",
    }
}

console.log(API.User.comments)
console.log(API.Post.details)

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

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