No index signature with a parameter of type 'string' was found on type 'Query'

Viewed 40

I'm using accesscontrol npm package for RBAC(role based access control) in my api this is my code for checking if the user has permission on resource or not:

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.'
    );
};

In nodejs this function is working just fine. but when I try it with typescript I'm getting this error:

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'.

from

  const permission = ac.can(role)[action](resource);
1 Answers

I found the solution after reading the typescript docs specifically https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-aliases, union, and string literal.

I just defined the types of the action using string-literal, union, and types-aliases in typescript and annotated the action type to this and everything is just working fine:

type ActionType = 'createAny' | 'updateAny' | 'deleteAny' | 'readAny';

Below is the full source code:

type ActionType = 'createAny' | 'updateAny' | 'deleteAny' | 'readAny';

export const checkUserPermission = async (
  res: Response,
  role: string,
  resource: string,
  action: ActionType
) => {
  const userRole = await Role.findOne({ name: role });
  if (!userRole) return sendErrorResponse(res, 401, '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.'
    );
};
Related