OliverRadini
OliverRadini

Reputation: 6467

Build array from enum

I've been struggling to understand what it is about this code that is causing a problem. It'd be great if someone could explain what leads to the problem, and perhaps how it may be solved.

In my app I'm trying to use an enum to define the routes used by a router. This was working in certain places but for some reason, in the context I'm now using the enum, it isn't working.

Where it works, it may look something like this:

history.push(routes.testPage)

Where it doesn't work, it looks something like this:

const enum routes {
    index = '/',
    testPage = '/test',
}

const adminRoutes = [
    routes.testPage,
];

const routeIsAdmin = (route: string) => adminRoutes.indexOf(route) > -1;

The error I get in this instance is:

Argument of type 'string' is not assignable to parameter of type 'routes'

I've created an example of this code on the typescript playground.

Would someone be able to provide any insight on this?


Edit

For further clarity, adding any string to the array adminRoutes means that this works with no problems. This is not really a workaround which I'd like to use, but perhaps it helps to explain the problem.

Upvotes: 0

Views: 76

Answers (1)

zeh
zeh

Reputation: 10659

You can't build an array from an enum. Think of enum definition as something that is lost during transpilation. It only exists for checking during that process. They'd still be present as strings in the generated code, but only when referenced by value.

In your specific case, you could just do a route as string to convert them to string...

const routeIsAdmin = (route: routes) => {
    adminRoutes.indexOf(route as string) > -1;
}

...but that's a pretty bad smell since you're now depending on routes being directly linked to the actual paths.

For all intents and purposes, you should think of enums mostly as different instances of a thing with no significant value attached to it. Sure, it does have a value internally, but it's best ignored. The way I see it, if your enums wouldn't work if the underlying string values were replaced with number values, then it's the wrong approach.

My honest opinion? Semantically, you don't want enums at all, you want a list of actual strings.

const routes = {
    index: '/',
    testPage: '/test',
};

const adminRoutes = [
    routes.testPage,
];

const routeIsAdmin = (route: string) => adminRoutes.indexOf(route) > -1;

And then you could still do things like Object.keys(routes), etc.

Upvotes: 1

Related Questions