Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next Auth V5 Augment Typescript User Interface doesnt work #9253

Closed
cexra opened this issue Nov 27, 2023 · 11 comments · Fixed by #9462
Closed

Next Auth V5 Augment Typescript User Interface doesnt work #9253

cexra opened this issue Nov 27, 2023 · 11 comments · Fixed by #9462
Labels
documentation Relates to documentation triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.

Comments

@cexra
Copy link

cexra commented Nov 27, 2023

What is the improvement or update you wish to see?

next auth js provides documentation that does not work to augment the User interface in the @auth/core module.

Is there any context that might help us understand?

from the existing documentation we can augment the User interface like the method below

next-auth.d.ts

import { JWT } from '@auth/core/jwt'
import { type DefaultSession } from 'next-auth'

declare module '@auth/core' {
  interface Session {
    user: {
      id: string
      identifier: string
      role: 'USER' | 'ADMIN'
      name: string
    } & DefaultSession['user']
  }

  interface User {
    id: string
    identifier: string
    name: string
    role: 'USER' | 'ADMIN'
  }
}

declare module '@auth/core/jwt' {
  interface JWT {
    identifier: string
    name: string
    role: 'USER' | 'ADMIN'
  }
}

augment Session interface and JWT interface it works. but augment User interface does not work. my purpose of augmenting the User interface is to persist the role attribute on the User object, so that I can store it on the Session object.

auth.config.ts

import type { NextAuthConfig } from 'next-auth'

export const authConfig = {
  callbacks: {
    jwt({ token, user }) {
      if (user) token.role = user.role // Property 'role' does not exist on type 'User | AdapterUser'. Property 'role' does not exist on type 'User'.ts(2339)
      return token
    },

    session({ session, token }) {
      session.user.role = token.role
      return session
    },
  },
} satisfies NextAuthConfig

Does the docs page already exist? Please link to it.

https://authjs.dev/getting-started/typescript?frameworks=next

@cexra cexra added documentation Relates to documentation triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime. labels Nov 27, 2023
@judewang
Copy link

@cexra Try using @auth/core/types rather than @auth/core, that worked for me.

@cexra
Copy link
Author

cexra commented Nov 27, 2023

yes the solution works but only partially, the solution solves the problem on jwt and session callback. but why user.name is still a string | null | undefined when I think user.name should be a string only. can anyone help me how to augment this type

@Constantiner
Copy link

Constantiner commented Nov 29, 2023

import "next-auth";

declare module "next-auth" {
	interface User {
		role: "SUPER" | "USER";
	}

	interface Session {
		user?: User;
	}
}

declare module "@auth/core/jwt" {
	interface JWT {
		role: "SUPER" | "USER";
	}
}

This works for me.

@KrisTemmerman
Copy link

I tried both ways, and i run into the same issue:
Property 'id' does not exist on type '{ name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }'.

import NextAuth from "next-auth";
import Discord from "next-auth/providers/discord";
import type { NextAuthConfig } from "next-auth";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { db } from "@/app/db";
import { pgTable } from "./db/schema";
import { env } from "@/env.mjs";

enum UserRole {
  Admin = "admin",
  User = "user",
  Free = "free",
}

declare module "@auth/core/types" {
  interface Session {
    user: {
      id: string;
      // ...other properties
      role: UserRole;
    } & DefaultSession["user"];
  }

  interface User {
    // ...other properties

    role: UserRole;
  }
}

export const config = {
  theme: {
    logo: "https://next-auth.js.org/img/logo/logo-sm.png",
  },
  providers: [
    Discord({
      clientId: env.DISCORD_CLIENT_ID,
      clientSecret: env.DISCORD_CLIENT_SECRET,
    }),
  ],
  adapter: DrizzleAdapter(db, pgTable),

  callbacks: {
    session: ({ session, user }) => ({
      ...session,
      user: {
        ...session.user,
        id: user.id,
        role:session.user?.role
      },
    }),
  },
} satisfies NextAuthConfig;

export const { handlers, auth } = NextAuth(config);

@Constantiner
Copy link

Have you tried to put your augmented types into a separate .d.ts file?

@KrisTemmerman
Copy link

I needed to update my package to next-auth": "5.0.0-beta.4 and drizzle-adapter:"^0.3.9", and could just run it inline.
Thanks all for confirming it was me and not NextAuth.

import NextAuth from "next-auth";
import Discord from "next-auth/providers/discord";
import type { NextAuthConfig } from "next-auth";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { db } from "@/app/db";
import { pgTable } from "./db/schema";
import { env } from "@/env.mjs";

enum UserRole {
  Admin = "admin",
  User = "user",
  Free = "free",
}

declare module "@auth/core/types" {
  interface Session {
    user: {
      id: string;
      // ...other properties
      role: UserRole;
    } 
  }

  interface User {
    // ...other properties

    role: UserRole;
  }
}

export const config = {
  theme: {
    logo: "https://next-auth.js.org/img/logo/logo-sm.png",
  },
  providers: [
    Discord({
      clientId: env.DISCORD_CLIENT_ID,
      clientSecret: env.DISCORD_CLIENT_SECRET,
    }),
  ],
  adapter: DrizzleAdapter(db, pgTable),

  callbacks: {
    session: ({ session, user }) => ({
      ...session,
      user: {
        ...session.user,
        id: user.id,
        role: session.user?.role,
      },
    }),
  },
} satisfies NextAuthConfig;

export const { handlers, auth } = NextAuth(config);

@andreluis-oliveira
Copy link

@cexra Try using @auth/core/types rather than @auth/core, that worked for me.

thanks bro

@ypanagidis
Copy link

ypanagidis commented Dec 4, 2023

I gave this a go today and no luck still unfortunately. How come this works for you guys when this is still open? #8561

@chungweileong94
Copy link
Contributor

So I spend quite some time debugging this, as both @auth/core & @auth/core/types doesn't work for me, and I don't think adding the /types is really necessary.

I managed to solve it by making the user optional, which make sense as the user can be undefined when user is not login.

declare module "next-auth" {
  interface Session {
    user?: {
      id: string;
      // ...other properties
      role: UserRole;
    } 
  }
}

Notice that it also works with next-auth in my case, so I believe it should also works with @auth/core & @auth/core/types.

@rvndev
Copy link

rvndev commented Mar 13, 2024

I've tested various releases of next-auth@beta, however, I am still unable to overwrite the default values in the User interface. I saved the following into next-auth.d.ts, however, I am still getting an error when I try to assign a Number to id in authorize().

declare module "next-auth" {
  interface User {
    id: number;
  }

  interface Session {
    user?: User;
  }
}

declare module "@auth/core" {
  interface User {
    id: number;
  }
}

declare module "@auth/core/types" {
  interface User {
    id: number;
  }
}

@ndom91
Copy link
Member

ndom91 commented Mar 13, 2024

@rvndev did you include your next-auth.d.ts in your tsconfig.json types?

I've added this snippet in my auth.config.ts and it seemed to work:

declare module "next-auth" {
  interface Session {
    user: {
      address: string
    } & User
  }

  interface User {
    foo?: string
  }
}

Check this out for more details: https://authjs.dev/getting-started/typescript

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Relates to documentation triage Unseen or unconfirmed by a maintainer yet. Provide extra information in the meantime.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants