node.jstypescriptcompiler-errorsjwt

How to resolve TypeScript type error with jwt.sign and Secret in jsonwebtoken?


I'm working on a TypeScript project where I'm using the jsonwebtoken library to generate and verify JWT tokens. However, I'm encountering a type error when trying to use the jwt.sign function.

import jwt, { Secret, JwtPayload } from "jsonwebtoken";

const JWT_SECRET: Secret = process.env.JWT_SECRET || "kala__30191";
const EXPIRE: string = process.env.JWT_EXPIRE || "30d";

export function generateToken(payload: Record<string, any>): string {
  return jwt.sign(payload, JWT_SECRET, { expiresIn: EXPIRE });
}

export function verifyToken(token: string): Promise<JwtPayload | string> {
  return new Promise((resolve, reject) => {
    jwt.verify(token, JWT_SECRET, (err, decoded) => {
      if (err) {
        return reject(err);
      }
      resolve(decoded as JwtPayload);
    });
  });
}

But I am getting the some error, that i cannot understand.

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: Secret | Buffer<ArrayBufferLike> | 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: Secret | Buffer<ArrayBufferLike> | PrivateKeyInput | JsonWebKeyInput, callback: SignCallback): void', gave the following error.
Object literal may only specify known properties, and 'expiresIn' does not exist in type 'SignCallback'. (ts 2769)

I have installed the jsonwebtoken library and its type definitions. I'm looking for guidance on how to fix this type error.


Solution

  • jwt.sign expects the expiresIn option to be of type number | StringValue | undefined but you defined EXPIRE to be a string.

    I checked the definition of StringValue (here) and it is basically a way to get type safety for constructs like 30d which you used for a value.

    Simply not forcing EXPIRE to be a string and letting the type system infer the proper type should be sufficient to fix your problem:

    const EXPIRE = process.env.JWT_EXPIRE || "30d";
    

    This might get you a new issue because process.env.JWT_EXPIRE is probably defined as string | undefined as well. In this case you may have to bite the bullet and define it to be any:

    const EXPIRE = process.env.JWT_EXPIRE as any || "30d";
    

    Note: You could (should?) also add an additional dependency @types/ms and use the StringValue type that it defines.

    import type { StringValue } from "ms";
    const EXPIRE = process.env.JWT_EXPIRE as StringValue || "30d";