Home > database >  Typescript error: Types of property 'token' are incompatible
Typescript error: Types of property 'token' are incompatible

Time:04-06

I am creating login/logout/fogotpass logic with JSON WEB TOKEN and The API Context in my react project. I am having a problem with typescript with value error in my <AuthContext.Provider value={contextValue}>
Not sure how I should set the types here. Typescript Error

import React, { useState, useEffect, useCallback } from "react";

type ContextObj = {
  token: string | null | undefined;
  isLoggedIn: any;
  login: (token: string, expirationTime: any) => void;
  logout: () => void;
};

let logoutTimer: any;

const AuthContext = React.createContext({
  token: "",
  isLoggedIn: false,
  login: (token: any) => {},
  logout: () => {},
});

const calculateRemainingTime = (expirationTime: any) => {
  const currentTime = new Date().getTime();
  const adjExpirationTime = new Date(expirationTime).getTime();

  const remainingDuration = adjExpirationTime - currentTime;

  return remainingDuration;
};

const retrieveStoredToken = () => {
  const storedToken = localStorage.getItem("token");
  const storedExpirationDate = localStorage.getItem("expirationTime");

  const remainingTime = calculateRemainingTime(storedExpirationDate);

  if (remainingTime <= 3600) {
    localStorage.removeItem("token");
    localStorage.removeItem("expirationTime");
    return null;
  }

  return {
    token: storedToken,
    duration: remainingTime,
  };
};

export const AuthContextProvider = (props: any) => {
  const tokenData = retrieveStoredToken();

  let initialToken;
  if (tokenData) {
    initialToken = tokenData.token;
  }

  const [token, setToken] = useState(initialToken);

  const userIsLoggedIn = !!token;

  const logoutHandler = useCallback(() => {
    setToken(null);
    localStorage.removeItem("token");
    localStorage.removeItem("expirationTime");

    if (logoutTimer) {
      clearTimeout(logoutTimer);
    }
  }, []);

  const loginHandler = (token: string, expirationTime: any) => {
    setToken(token);
    localStorage.setItem("token", token);
    localStorage.setItem("expirationTime", expirationTime);

    const remainingTime = calculateRemainingTime(expirationTime);

    logoutTimer = setTimeout(logoutHandler, remainingTime);
  };

  useEffect(() => {
    if (tokenData) {
      console.log(tokenData.duration);
      logoutTimer = setTimeout(logoutHandler, tokenData.duration);
    }
  }, [tokenData, logoutHandler]);

  const contextValue: ContextObj = {
    token: token,
    isLoggedIn: userIsLoggedIn,
    login: loginHandler,
    logout: logoutHandler,
  };

  return (
    <AuthContext.Provider value={contextValue}>
      {props.children}
    </AuthContext.Provider>
  );
};

export default AuthContext;

CodePudding user response:

you've forgotten about adding expirationTime in your creating context login key function argument part. your contextType:

type ContextObj = {
  token: string ; //change this too
  isLoggedIn: any; //change this to boolean too
  login: (token: string, expirationTime: any) => void;
  logout: () => void;
};

your context

const AuthContext = React.createContext({
  token: "",
  isLoggedIn: false,
  login: (token , expirationTime) => {}, //adding expirationTime
  logout: () => {},
});

CodePudding user response:

You have a type issue with your token, which can be null. But currently, you didn't specified it, so you should do it this way:

const [token, setToken] = useState<string|undefined|null>(initialToken); 

By default, if you don't specify it, the type would be only string or undefined

  • Related