网站搜索

javascript - 如何让 TypeScript 枚举限制为特定数字


我使用数字枚举类型来设置页面的访问代码:

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

我希望这个路由接受一个类型为 AdminAccess 的参数,这样它只能在以上值之间选择:

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

然而类型检查没有按我预期的那样工作,只要我输入数字,检查就会通过。但我想要的是,你只能输入 AdminAccess.None、AdminAccess.Dashboard 等。

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

我该如何让它工作?

答案#1

这个问题可能是“TypeScript 中 enum 的意义是什么”的重复。将那里的答案翻译到你的问题上,大致是这样的:

无论好坏,TypeScript 中的数字枚举都可以与 number 相互赋值,这直接导致了你看到的问题。你可能会有更好的效果,放弃使用 enum,转而使用 namespace 和 type 的组合,并使用显式的数字字面量类型,如下所示:

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)

请注意,为了使其工作,像 1 << 2 这样的计算枚举需要被它们的数值字面量值替换,如 4(数值计算不会产生数值字面量类型)。

希望这能帮到你;祝你好运!

代码链接