I recently found and started testing create-t3-app as a new base for NextJS projects because it takes care of a lot of boilerplate setup for things like TypeScript, trpc, prisma, and next-auth so it'd save me a ton of time. While that's relevant, I don't think it's the source of my problem. My problem is that I use a MySQL database with auto-incrementing user IDs but it seems like the types for the next-auth
package are forcing me to use a string (DefaultUser
in next-auth/core/types.d.ts
and AdapterUser
in next-auth/adapters.d.ts
both set the type of id to string and the comments say UUIDs). Thinking that I could possibly extend what's there to support numeric user IDs, I added this to next-auth.d.ts
:
import { DefaultSession, DefaultUser } from 'next-auth'
declare module 'next-auth' {
interface User extends DefaultUser {
id: number;
}
interface Session {
user?: {
id: number;
} & DefaultSession['user'];
}
}
Which seems to work most places except in [...nextauth].ts
where it is giving me this error
Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'.ts(2322)
On the session.user.id = user.id
line in this section of code
export const authOptions: NextAuthOptions = {
// Include user.id on session
callbacks: {
session({ session, user }) {
if (session.user) {
session.user.id = user.id
}
return session
}
},
adapter: PrismaAdapter(prisma),
providers: []
}
export default NextAuth(authOptions)
The TypeScript error goes away if I delete the id: string;
line from the AdapterUser
from next-auth/adapters.d.ts
which then falls back to id: number;
because I set that on User
export interface AdapterUser extends User {
id: string; // <-- I removed this
email: string;
emailVerified: Date | null;
}
I don't think I should have to modify the library's types to support numeric user IDs but I'm all out of ideas how to solve this and haven't found answers online. Or should I not be using numeric IDs even though my database does? If it helps, I'm using
next 12.3.1
next-auth 4.12.3
react 18.2.0
react-dom 18.2.0
superjson 1.9.1
zod 3.18.0
eslint 8.22.0
postcss 8.4.14
prettier 2.7.1
prisma 4.4.0
tailwindcss 3.1.6
typescrypt 4.8.0
Unfortunately it doesn't seem possible to "patch up" or change the types the library has - even trying to change NextAuthOptions
doesn't work since subsequent property definitions must have the same type. In the meantime, you'll have to use a runtime check/coercion or cast:
export const authOptions: NextAuthOptions = {
// Include user.id on session
callbacks: {
session({ session, user }) {
if (session.user) {
if (typeof user.id !== "number") throw new Error("id should a number");
session.user.id = user.id // OK
// session.user.id = +user.id // more dangerous but still works
// session.user.id = user.id as number // also dangerous
}
return session
}
},
adapter: PrismaAdapter(prisma),
providers: []
}