[GH-ISSUE #3033] Username & admin plugin type issues #9439

Closed
opened 2026-04-13 04:54:18 -05:00 by GiteaMirror · 5 comments
Owner

Originally created by @twiddlecoding on GitHub (Jun 15, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/3033

I'm using better-auth in a setup where the client and server are separated (no monorepo). I've activated the username plugin on both the server and the client, and it's working as expected. However, when trying to list users client side using the admin plugin, I get a type-error when trying to access the username property of UserWithRole. Here is my client-side code:

authclient.ts

import { createAuthClient } from "better-auth/react"
import { adminClient } from "better-auth/client/plugins"
import { usernameClient } from "better-auth/client/plugins"
import { ac, admin, view, basic, service, advanced } from "./permissions"
export const authClient = createAuthClient({
    basePath: "/api/auth",
    plugins: [
        adminClient({
          ac,
            roles: {
                view,
                basic,
                service,
                advanced,
                admin
            }
        }),
        usernameClient()
    ],
    ...(process.env.NODE_ENV?.includes('development') && {
    baseURL: "http://localhost:3000",
    
  })
    
})  

export type Session = typeof authClient.$Infer.Session

Accounts.tsx (snippets)


import { authClient } from "@/lib/auth-client"

useEffect(() => {
    async function fetchUsers() {
    const response = await authClient.admin.listUsers({
      query: {
        limit: 10,
      }
    }); 
    if (response?.data?.users){
      const tempusers = response?.data?.users.map(user => (
        {
          id: user.id,
          name: user.name,
          username: user.username, //user.username is marked with a type error.
          role: user.role,
          email: user.email,
        }
      ));
      setUsers(tempusers); 
    }              
  }

  fetchUsers();
  }, [reloadusers]);

On user.username, I get the error:

Property 'username' does not exist on type 'UserWithRole'.

However, at runtime, the property username is accessible here. Where am I going wrong?

A huge thank you in advance!

Originally posted by @twiddlecoding in https://github.com/better-auth/better-auth/discussions/2870

Originally created by @twiddlecoding on GitHub (Jun 15, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/3033 I'm using better-auth in a setup where the client and server are separated (no monorepo). I've activated the username plugin on both the server and the client, and it's working as expected. However, when trying to list users client side using the admin plugin, I get a type-error when trying to access the username property of UserWithRole. Here is my client-side code: authclient.ts ``` import { createAuthClient } from "better-auth/react" import { adminClient } from "better-auth/client/plugins" import { usernameClient } from "better-auth/client/plugins" import { ac, admin, view, basic, service, advanced } from "./permissions" export const authClient = createAuthClient({ basePath: "/api/auth", plugins: [ adminClient({ ac, roles: { view, basic, service, advanced, admin } }), usernameClient() ], ...(process.env.NODE_ENV?.includes('development') && { baseURL: "http://localhost:3000", }) }) export type Session = typeof authClient.$Infer.Session ``` Accounts.tsx (snippets) ``` import { authClient } from "@/lib/auth-client" useEffect(() => { async function fetchUsers() { const response = await authClient.admin.listUsers({ query: { limit: 10, } }); if (response?.data?.users){ const tempusers = response?.data?.users.map(user => ( { id: user.id, name: user.name, username: user.username, //user.username is marked with a type error. role: user.role, email: user.email, } )); setUsers(tempusers); } } fetchUsers(); }, [reloadusers]); ``` On user.username, I get the error: > Property 'username' does not exist on type 'UserWithRole'. However, at runtime, the property username is accessible here. Where am I going wrong? A huge thank you in advance! _Originally posted by @twiddlecoding in https://github.com/better-auth/better-auth/discussions/2870_
GiteaMirror added the lockedbug labels 2026-04-13 04:54:18 -05:00
Author
Owner

@ImEins commented on GitHub (Jun 29, 2025):

Maybe you’ve already found a solution, but if not, or for anyone looking later, you can cast the users to your extended type like this:

// import { UserWithRole } from 'better-auth/plugins/admin'

interface ExtendedUserWithRole extends UserWithRole {
  username: string
  displayUsername: string
}

const users = await authClient.admin.listUsers({ query: {} })

const usersWithUsername = users.data?.users as ExtendedUserWithRole[];
<!-- gh-comment-id:3016701233 --> @ImEins commented on GitHub (Jun 29, 2025): Maybe you’ve already found a solution, but if not, or for anyone looking later, you can cast the users to your extended type like this: ```ts // import { UserWithRole } from 'better-auth/plugins/admin' interface ExtendedUserWithRole extends UserWithRole { username: string displayUsername: string } const users = await authClient.admin.listUsers({ query: {} }) const usersWithUsername = users.data?.users as ExtendedUserWithRole[]; ```
Author
Owner

@twiddlecoding commented on GitHub (Jun 30, 2025):

Maybe you’ve already found a solution, but if not, or for anyone looking later, you can cast the users to your extended type like this:

// import { UserWithRole } from 'better-auth/plugins/admin'

interface ExtendedUserWithRole extends UserWithRole {
username: string
displayUsername: string
}

const users = await authClient.admin.listUsers({ query: {} })

const usersWithUsername = users.data?.users as UserWithUsername[];

Thank you for your reply and the solution! I will go with this solution! 😊👌

<!-- gh-comment-id:3018106809 --> @twiddlecoding commented on GitHub (Jun 30, 2025): > Maybe you’ve already found a solution, but if not, or for anyone looking later, you can cast the users to your extended type like this: > > // import { UserWithRole } from 'better-auth/plugins/admin' > > interface ExtendedUserWithRole extends UserWithRole { > username: string > displayUsername: string > } > > const users = await authClient.admin.listUsers({ query: {} }) > > const usersWithUsername = users.data?.users as UserWithUsername[]; Thank you for your reply and the solution! I will go with this solution! 😊👌
Author
Owner

@ImEins commented on GitHub (Jul 7, 2025):

I actually gave you the wrong answer. In the last line, you should use ExtendedUserWithRole instead of UserWithUsername. Sorry for the oversight.

<!-- gh-comment-id:3045366512 --> @ImEins commented on GitHub (Jul 7, 2025): I actually gave you the wrong answer. In the last line, you should use `ExtendedUserWithRole` instead of `UserWithUsername`. Sorry for the oversight.
Author
Owner

@animatern commented on GitHub (Sep 4, 2025):

Maybe you’ve already found a solution, but if not, or for anyone looking later, you can cast the users to your extended type like this:

// import { UserWithRole } from 'better-auth/plugins/admin'

interface ExtendedUserWithRole extends UserWithRole {
username: string
displayUsername: string
}

const users = await authClient.admin.listUsers({ query: {} })

const usersWithUsername = users.data?.users as ExtendedUserWithRole[];

In addition to that, you might need to export interface UserWithRole extends User from within the admin plugin (node_modules/better-auth/dist/plugins/admin/index.d.ts)

<!-- gh-comment-id:3251231534 --> @animatern commented on GitHub (Sep 4, 2025): > Maybe you’ve already found a solution, but if not, or for anyone looking later, you can cast the users to your extended type like this: > > // import { UserWithRole } from 'better-auth/plugins/admin' > > interface ExtendedUserWithRole extends UserWithRole { > username: string > displayUsername: string > } > > const users = await authClient.admin.listUsers({ query: {} }) > > const usersWithUsername = users.data?.users as ExtendedUserWithRole[]; In addition to that, you might need to export interface UserWithRole extends User from within the admin plugin (node_modules/better-auth/dist/plugins/admin/index.d.ts)
Author
Owner

@dosubot[bot] commented on GitHub (Dec 4, 2025):

Hi, @twiddlecoding. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You reported a TypeScript type error when accessing the "username" property on "UserWithRole" from the admin plugin client-side.
  • Commenters suggested casting the user list to an extended interface including "username" and "displayUsername" to fix the type mismatch.
  • Minor naming corrections and exporting the extended interface from the admin plugin's type definitions were also recommended.
  • You acknowledged the solution and planned to use the casting approach.
  • The issue is considered resolved with the casting workaround and type definition export suggestion.

Next Steps:

  • Please confirm if this issue is still relevant with the latest version of better-auth by commenting here.
  • If no further updates are provided, I will automatically close this issue in 7 days.

Thanks for your understanding and contribution!

<!-- gh-comment-id:3613025407 --> @dosubot[bot] commented on GitHub (Dec 4, 2025): Hi, @twiddlecoding. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You reported a TypeScript type error when accessing the "username" property on "UserWithRole" from the admin plugin client-side. - Commenters suggested casting the user list to an extended interface including "username" and "displayUsername" to fix the type mismatch. - Minor naming corrections and exporting the extended interface from the admin plugin's type definitions were also recommended. - You acknowledged the solution and planned to use the casting approach. - The issue is considered resolved with the casting workaround and type definition export suggestion. **Next Steps:** - Please confirm if this issue is still relevant with the latest version of better-auth by commenting here. - If no further updates are provided, I will automatically close this issue in 7 days. Thanks for your understanding and contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9439