2

I use a numeric enum type to set a page's access code:

export enum AdminAccess {
  None = 0,
  Dashboard = 1 << 0,
  ModifyUserInfo = 1 << 1,
  Publish = 1 << 2
}

And I want the route to take a parameter which is type AdminAccess, such that it can only choose between the values above:

export interface AuthRouteProps {
  children: JSX.Element;
  path: string;
  pageIdentity: AdminAccess;
  exact?: boolean;
}

However the type check didn't work as I expected, the check passes as long as I input number. But what I want is that you can only input AdminAccess.None, AdminAccess.Dashboard and etc.

<AuthRoute
  path={"somepath"}
  pageIdentity={AdminAccess.ModifyUserInfo} // pass check
  children={<ModifyUserInfoPage />}
/>
<AuthRoute
  path={"somepath"}
  pageIdentity={897654987} // also pass check
  children={<ModifyUserInfoPage />}
/>

How can I make that work?

liuliang
  • 395
  • 1
  • 3
  • 14
  • also see [microsoft/TypeScript#17734](https://github.com/microsoft/TypeScript/issues/17734) – jcalz Dec 06 '19 at 01:36

1 Answers1

2

This question is possibly a duplicate of "What is the significance of enum in TypeScript". Translating the answer there to your problem yields something like this:

For better or worse, numeric enums in TypeScript are assignable both to and from number, which directly leads to the problem you're seeing. You might have better luck abanadoning enum in favor of a combination of a namespace and a type using explicit numeric literal types, like this:

export namespace AdminAccess {
  export const None = 0
  export const Dashboard = 1
  export const ModifyUserInfo = 2
  export const Publish = 4;
}
export type AdminAccess = typeof AdminAccess[keyof typeof AdminAccess];

const good: AdminAccess = AdminAccess.ModifyUserInfo; // okay
const bad: AdminAccess = 289849284924; // error
//    ~~~ <---
// Type '289849284924' is not assignable to type '0 | 1 | 2 | 4'.(2322)

Note that the computed enums like 1 << 2 need to be replaced with their numeric literal values like 4 for this to work (numeric computations won't result in numeric literal types).

Hope that helps; good luck!

Link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360