Emad Baqeri
Emad Baqeri

Reputation: 2692

can't define function return type properly on typescript

This is the function that I have implemented for decoding the token with the aid of jsonwebtoken there is problem with return type that I have defined for the function,


import jwt, { decode } from "jsonwebtoken";

export const authentication = (
  token: string
): {
  error: { [message: string]: Error } | null;
  token: { [adminID: string]: string } | null | string;
} => {
  const decodedToken = jwt.decode(token);
  return {
    error: decodedToken
      ? null
      : {
          message: new Error("invalid error"),
        },
    token: decodedToken ? decodedToken : null,
  };
};

I'm trying to utilize the function like the code snippet below

  const { token, error } = authentication(context.headers.authorization);
  if (error) {
    throw new Error(error.message.toString());
  }

  const { adminID } = token;
  console.log("this is admin id", adminID);

In this part when I'm going to get adminID by object destructuring type script throws an error in like this

 Property 'adminID' does not exist on type 'string | { [adminID: string]: string; } | null'.

15   const { adminID } = token;

I need to mention that everything is working properly and I can get the adminID from token but typescript is blaming about this. any idea would be appreciated.

Upvotes: 0

Views: 228

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170745

{ [adminID: string]: string } is an index signature: it means an object that can be indexed with any string (and the name for the string parameter is adminID) and return a string. For an object with an adminID property of type string you want { adminID: string } instead (and probably error: { message: Error } | null as well).

And even better, use a discriminated (or tagged) union instead of two fields one of which must be null. Approximately like this:

export const authentication = (
  token: string
): { kind: "error", error: Error } | { kind: "token", adminId: string }
  const decodedToken = jwt.decode(token);
  return decodedToken
      ? { kind: "token", ...decodedToken }
      : { kind: "error", error: new Error("invalid error") };
};

Of course code consuming it will need to be changed as well:

const authResult = authentication(context.headers.authorization);
if (authResult.kind === "error") {
  throw new Error(authResult.error.toString());
}

const { adminID } = authResult.token;
console.log("this is admin id", adminID);

Upvotes: 1

Related Questions