You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用accesscontrol库时TypeScript出现索引签名类型错误

解决AccessControl包在TypeScript中的索引类型错误

我在API中使用accesscontrol npm包实现RBAC(基于角色的访问控制),用于检查用户对资源的权限,Node.js环境下代码运行正常,但切换到TypeScript时出现类型错误。

原代码

export const checkUserPermission = async (
  req: Request,      
  role: string,
  resource: string,
  action = 'readAny'
) => {
  const userRole = await Role.findOne({ name: role });
  if (!userRole) return sendErrorResponse(res, 400, 'Role is not exists.');
  const grantLists = await getPermissionsBasedOnRole(role);
  if (grantLists.length === 0)
    return sendErrorResponse(
      res,
      401,
      'Permission is not assigned for this role. please assign and try again.'
    );
  const ac = new AccessControl(grantLists);
  const permission = ac.can(role)[action](resource);
  if (!permission.granted)
    return sendErrorResponse(
      res,
      500,
      'You have no permission to perform this action.'
    );
};

报错信息

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Query'.
  No index signature with a parameter of type 'string' was found on type 'Query'.

报错位置:const permission = ac.can(role)[action](resource);

解决方法

1. 限定action参数的合法类型

TypeScript报错是因为无法确认传入的action字符串对应Query类型上的合法方法,直接限定参数类型为Query的键值即可:

import { AccessControl, Query } from 'accesscontrol';

export const checkUserPermission = async (
  req: Request,      
  role: string,
  resource: string,
  action: keyof Query = 'readAny'
) => {
  // 原有逻辑不变
  const permission = ac.can(role)[action](resource);
};

2. 使用类型断言绕过检查

如果需要保持action为string类型,可以通过类型断言告诉TypeScript该索引是合法的:

const permission = (ac.can(role) as Record<string, (resource: string) => any>)[action](resource);

3. 使用AccessControl的显式调用语法

改用execute方法的显式调用方式,避免动态索引:

const permission = ac.can(role).execute(action).on(resource);

内容的提问来源于stack exchange,提问作者H_POYA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 23:15:40