Next.js Discord

Discord Forum

NextAuth and typeError with id.

Answered
Yellow croaker posted this in #help-forum
Open in Discord
Yellow croakerOP
Hello im using NextAuth and i have a problem with my types.
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import { PrismaClient } from '@prisma/client';
import { Session } from 'next-auth';
import { User } from 'next-auth';

const prisma = new PrismaClient();

export const authOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID ?? '',
      clientSecret: process.env.GOOGLE_SECRET ?? '',
    }),
  ],
  callbacks: {
    async session({ session, user }: { session: Session; user: User }) {
      if (session?.user) {
        // Assign the user's ID to the session's user object
        session.user.id = user.id;
      }
      return session;
    },
  },
};

export const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };


I get error at session.user.id
Property 'id' does not exist on type '{ name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }'.ts(2339)
any

I tried to fix this by adding a custom interface, but that does not seem to work neither
interface CustomSession extends Session {
    user: Session['user'] & { 
        id: string; 
    } 
}


How i should fix approach this problem to get rid of the typeError?
Answered by Yellow croaker
Thanks for the insight, I now have now a better grasp of next auth typing.
View full answer

48 Replies

Yellow croakerOP
I added this to the top of the auth file:

import { Session, User, DefaultSession } from 'next-auth';

// Import the types
declare module 'next-auth' {
  interface Session {
    user: DefaultSession['user'] & {
      id: string;
    };
  }
...


callbacks: {
    async session({ session, user }: { session: Session; user: User }) {
      if (session?.user) {
        // Assign the user's ID to the session's user object
        console.log('session before', session);
        session.user.id = user.id;
        console.log('session', session.user);
      }
      return session;
}
Northeast Congo Lion
declare module 'next-auth' {
  interface Session {
    user: {
      id: string;
    }
  }
}
i used the same approach to exrtend a session and pass custom object
so I can read my user session like:
session.user.discord.name
as per example in docs 🙂
@Northeast Congo Lion perhaps u can do above?
Yellow croakerOP
I think with your suggestion, i should add all the other types like email etc?

Because im using the email at few point of my code:

  const account = await getCurrentUser();

  if (!account) {
    redirect('/api/auth/signin');
  }
  const user = await db.user.findUnique({
    where: { email: account.email ?? '' },
  });


export async function getCurrentUser() {
  const session = await getServerSession(authOptions);

  //console.log('session', session);
  return session?.user;
}
Northeast Congo Lion
i think email is part of next auth flow tbh
cant remember exactly
u can always try it
Yellow croakerOP
Then i should add
declare module 'next-auth' {
  interface Session {
    user: {
      id: string;
      email: string;
    };
  }
}
Northeast Congo Lion
but worst case scenario, just add field for email: string
correct
give it a try
let me know
i did this exact flow as I had to pass discord to session user
Yellow croakerOP
but what is the downside on using the defaultSession?
Northeast Congo Lion
tbh, not sure.
i tried default Session too
but after spending some time on docs, I noticed the above way to extend session
@Northeast Congo Lion but after spending some time on docs, I noticed the above way to extend session
Yellow croakerOP
Strange 🙂 well anyway maybe il go with the non defaultSession, but atleast now i have 2 different options to choose from
Northeast Congo Lion
it could be default session is implemented by session
e.g default session has name, email and image
you will know more if you view source code of next auth 😛
@Northeast Congo Lion you will know more if you view source code of next auth 😛
Yellow croakerOP
Yeah not sure how deep i want to dig 🤣
Northeast Congo Lion
yes
i think im correct haha
so TS will merge/overwrite the interfaces we declare.
where Default Session is what it says on the tin, default session with basic fields
Yellow croakerOP
Yeah so basically to if i want to use the "defaults" + id i could go with the defaultSession, and if i want to have something different i dont need to use defaultSession.

This feels like there is not really a correct way to do this?
Northeast Congo Lion
declare module 'next-auth' {
  interface Session {
    user: {
      id: string;
      email: string;
    };
  }
}
so this would give id & email
where as
declare module 'next-auth' {
  interface Session {
    user: {
      id: string;
    } & DefaultSession['user']

  }
}
would extend the default fields of name, email & image + id
Yellow croakerOP
Yeah email is default, because i need email and maybe image, then using defaultSession is better option.
Northeast Congo Lion
well
you will use
default session
and just extend id: string
becos image and email are part of user object by default
(updated example above)^
Yellow croakerOP
true
@Northeast Congo Lion (updated example above)^
Yellow croakerOP
Thanks for the insight, I now have now a better grasp of next auth typing.
Answer
Northeast Congo Lion
no problem at all
you can mark as solution if you found it satisfies 🙂