Search code examples
typescriptauthenticationnext.jsnext-auth

how to update the type of session in session callback in Next-auth when using Typescript


I am using typescript and my [...next-auth].tsx file looks like this:

import NextAuth, { Awaitable, Session, User } from "next-auth";
// import GithubProvider from "next-auth/providers/github";
import GoogleProvider from "next-auth/providers/google";

type ExtendedUserType = User & { username?: string; uid?: string };

export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    // ...add more providers here
  ],
  pages: {
    signIn: "/auth/signin", // for custom sign in page
  },
  callbacks: {
    async session({ session, token, user }): Awaitable<Session> {
      (session.user as ExtendedUserType).username = session.user?.name
        ?.split(" ")
        .join("")
        .toLocaleLowerCase();

      (session.user as ExtendedUserType).uid = token.sub;

      return session;
    },
  },
});


when fetching the session using the useSession hook I do not get Typescript autocompletion for the newly added keys - 'username', 'uid'

enter image description here

I am also getting this typescript error for Awaitable<Session> type enter image description here


Solution

  • The answer to the above is discussed here

    TLDR; next-auth.js.org/getting-started/typescript#module-augmentation

    Solution:

    Add the following types/**/*.ts in tsconfig.json:

    { 
      .
      .
      .
      "include": ["next-env.d.ts", "types/**/*.ts", "**/*.ts", "**/*.tsx"],
      .
      .
      .
    }
    

    Then add the following for session.user.

    types/next-auth.d.ts

    import NextAuth from "next-auth"
    
    declare module "next-auth" {
      /**
       * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
       */
      interface Session {
        user: {
          /** The user's name. */
          name: string
        }
      }
    }