I'm encountering the following TypeScript error:
"Argument of type 'string | undefined' is not assignable to parameter of type 'string | Buffer'."
I'm integrating NextAuth with my Next.js 14 application and configuring login credentials to compare passwords during login. However, I'm facing this error specifically with the input password in the following line:
const passwordOk =
existingUser && bcrypt.compareSync(password, existingUser.password)
and this is the full options file
import CredentialsProvider from "next-auth/providers/credentials"
import type { NextAuthOptions } from "next-auth"
import connectMongoDB from "@/lib/mongodb"
import bcrypt from "bcrypt"
import User from "@/models/user"
export const authOptions: NextAuthOptions = {
// Configure one or more authentication providers
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
// email: { label: "Email", type: "email", placeholder: "email" },
// password: { label: "Password", type: "password" },
email: {},
password: {},
},
async authorize(credentials, req) {
const email = credentials?.email
const password = credentials?.password
// Add logic here to look up the user from the credentials supplied
await connectMongoDB()
const existingUser = await User.findOne({ email })
const passwordOk =
existingUser && bcrypt.compareSync(password, existingUser.password)
if (passwordOk) {
// Any object returned will be saved in `ser` property of the JWT
return existingUser
} else {
// If you return null then an error will be displayed advising the user to check their details.
return null
// You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter
}
},
}),
],
}
I have tried to assign this type manually on the password but didn't work
const password: string | Buffer = credentials?.password
I also tried this
const passwordOk =
existingUser &&
password &&
bcrypt.compareSync(password, existingUser.password)
and the error disappeared, but I'm not sure if it is a best practice
credentials?.passwordmight returnundefinedbecause of Optional chaining?.andcompareSynccouldn't be evaluated with anundefinedas a first parameter, hence, you are seeing this error.From MDN
Since
passwordOkwill be affected bypasswordvalue, it's recommended to check for its value (and for the email as well) before continuing with the excution, though, a Guard Clause would be great here:This should remove the error.
Another solution that I don't really recommend in such cases (due to somehow breaking the typescript checking system) is to use non-null assertion operator and the syntax is pretty easy, simply postfix your password with exclamation mark, i.e.
credentials.password!this tells typescript that you are pretty sure that this expression will return a value and will never benullorundefined.