I’m writing a Mongoose user schema in TypeScript, and inside the schema methods, I want to generate JWT access tokens and refresh tokens.
I installed the required packages using:
npm i jsonwebtoken
npm i -D @types/jsonwebtoken
However, when I call jwt.sign(), I get this TypeScript error:
I wrote this code inside my Mongoose user schema method to generate an access token:
userSchema.methods.generateAccessToken = function (
this: IUseSchema & mongoose.Document,
): string {
if (!this._id) {
throw new ApiError(400, "Payload ID is missing");
}
if (!env.ACCESS_TOKEN_KEY) {
throw new ApiError(400, "ACCESS_TOKEN_KEY is missing in env");
}
if (!env.ACCESS_TOKEN_EXPIRY) {
throw new ApiError(400, "ACCESS_TOKEN_EXPIRY is missing in env");
}
const secretKey = env.ACCESS_TOKEN_KEY as Secret;
const expiresIn = env.ACCESS_TOKEN_EXPIRY as string;
return jwt.sign({ id: this._id }, secretKey, { expiresIn });
};
But I get an error on the line with jwt.sign.
I don’t understand what type safety I am missing here. Can someone explain what might be wrong?
No overload matches this call.
Overload 1 of 5, '(payload: string | object | Buffer<ArrayBufferLike>, secretOrPrivateKey: null, options?: (SignOptions & { algorithm: "none"; }) | undefined): string', gave the following error.
Argument of type 'Secret' is not assignable to parameter of type 'null'.
Type 'string' is not assignable to type 'null'.
Overload 2 of 5, '(payload: string | object | Buffer<ArrayBufferLike>, secretOrPrivateKey: Buffer<ArrayBufferLike> | Secret | PrivateKeyInput | JsonWebKeyInput, options?: SignOptions | undefined): string', gave the following error.
Type 'string' is not assignable to type 'number | StringValue | undefined'.
Overload 3 of 5, '(payload: string | object | Buffer<ArrayBufferLike>, secretOrPrivateKey: Buffer<ArrayBufferLike> | Secret | PrivateKeyInput | JsonWebKeyInput, callback: SignCallback): void', gave the following error.
Object literal may only specify known properties, and 'expiresIn' does not exist in type 'SignCallback'.
I’m passing the arguments like this (example):
jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: process.env.ACCESS_TOKEN_EXPIRY });
I created a jwt.sign, and in that, I added process.env.ACCESS_TOKEN_KEY and process.env.ACCESS_TOKEN_EXPIRY. But the issue is that it's not working properly in JWT. Even though I added safety measures, it still doesn't work as expected. So, I tried doing it like this: expiresIn: "30d". But since these are secure credentials (like a private key), they should be stored safely.
So my issue is: Why is it not working when I use process.env? I'm getting a "no overload" error.
process.env.JWT_SECREThas the typestring | undefinedthat's why you need to get the secret into a string variable likeconst secret = process.env.JWT_SECRET ?? '123'and pass it to jst like thisjwt.sign('111', secret, {})idavailable in JWT specification.payloadcan be anyobjectconst secretKey = env.ACCESS_TOKEN_KEY as Secretthough.undefined. See my answer for a better explanation