#Typescript error

1 messages · Page 1 of 1 (latest)

teal scarab
#

I am trying to restrict access to the admin panel to just superAdmins and admins both of which are roles on the user collection.

problem: I get the typescript error when i hover over users.access.admin access control function:

Type 'Access' is not assignable to type '(args?: any) => boolean | Promise<boolean>'.
 Type 'AccessResult | Promise<AccessResult>' is not assignable to type 'boolean | Promise<boolean>'.
   Type 'Where' is not assignable to type 'boolean | Promise<boolean>'.
     Type 'Where' is missing the following properties from type 'Promise<boolean>': then, catch, finally, [Symbol.toStringTag]ts(2322)
types.d.ts(311, 9): The expected type comes from property 'admin' which is declared here on type '{ create?: Access; read?: Access; readVersions?: Access; update?: Access; delete?: Access; admin?: (args?: any) => boolean | Promise<boolean>; unlock?: Access; }'```
teal scarab
#

Here is my Users collectio:

import { CollectionConfig } from "payload/types";
import isSuperAdmin from "../access/isSuperAdmin";
import isAdmin from "../access/isSuperAdmin";
import isSuperAdminOrAdmin from "../access/isSuperAdminOrAdmin";

const Users: CollectionConfig = {
  slug: "users",
  auth: {
    cookies: {
      // disabe "secure" property when in development mode, otherwise no cookies will be set
      // secure: process.env.PAYLOAD_ENV !== "development",
      sameSite: process.env.PAYLOAD_ENV === "testing" ? "none" : "lax",
    },
  },
  access: {
    create: isAdmin,
    admin: isSuperAdminOrAdmin,
  },
  admin: {
    useAsTitle: "email",
  },
  fields: [
    {
      name: "fullName",
      label: "Full Name",
      type: "text",
      // required: true,
    },
    {
      name: "phoneNumber",
      type: "number",
      label: "Phone Number",
      // required: true,
      unique: true,
    },
    {
      name: "transactionPin",
      type: "number",
      label: "Transaction Pin",
      // hidden: true, #uncomment this to make Transaction Pin to be visible in the admin UI
      // required: true,
      unique: true,
    },
    {
      name: "roles",
      type: "select",
      hasMany: true,
      saveToJWT: true,
      options: [
        {
          label: "Super Admin",
          value: "superAdmin",
        },
        {
          label: "Admin",
          value: "admin",
        },
        {
          label: "Api User",
          value: "apiUser",
        },
        {
          label: "Normal user",
          value: "normalUser",
        },
      ],
    },
  ],
};

export default Users;```
#

isSuperAdminOrAdmin function:

import { Access } from "payload/types";
import { User } from "../payload-types";

const isSuperAdminOrAdmin: Access<any, User> = async ({ req: { user } }) => {
  const isSuperAdmin = user?.roles?.includes("superAdmin");
  const isAdmin = user?.roles?.includes("admin");

  return Boolean(isSuperAdmin || isAdmin);
};

export default isSuperAdminOrAdmin;```
ripe lotus
#

Hi! Pretty much what the error says: all the access controls expect an Access type function (which returns a boolean OR a Where), but the admin one expect a function that returns a boolean. Because isSuperAdminOrAdmin is typed as Access, it means that it could, in theory, return either a boolean or a Where. Now looking at the function, it is clear it will only ever return a boolean, but Typescript doesn't know that.

If you are using Typescript >= 4.9, you can use the satisfies keyword to let Typescript infer a more precise type for the function (in which case it will consider it a function that return a boolean), while still satisfying the requirements of being an Access function. It would look like this:

const isSuperAdminOrAdmin = (({ req: { user } }) => {
  const isSuperAdmin = user?.roles?.includes("superAdmin");
  const isAdmin = user?.roles?.includes("admin");

  return Boolean(isSuperAdmin || isAdmin);
}) satisfies Access<any, User>;

I also removed the async as there wasn't any await inside the function

teal scarab
#

@ripe lotus I can't thank you enough, I am really grateful.
The error has been resolved.

If you don't mind, please where/how can I check the return type of Access function.

ripe lotus
pliant tundraBOT
teal scarab
#

It worked.
However, I couldn't see a Where return type anywhere, perhaps I may be missing something.

ripe lotus
#

The Where is part of the return type of the function. You need to do the same Ctrl+click maneuver on AccessResult