I'm working with React and Typescript and I'm logging in as a user.
When I try to access the response var I get the following error:
Object is of type 'unknown'.ts(2571)
const response: unknown
I think I'm not declaring something
This is my complete code:
import React, {createContext, useEffect, useState} from "react";
import { IAuthProvider, IContext, IUser } from "./types";
import { getUserLocalStorage, LoginRequest, setUserLocalStorage } from "./util";
export const AuthContext = createContext<IContext>({} as IContext)
export const AuthProvider = ({children}: IAuthProvider) => {
const [user, setUser] = useState<IUser | null>()
useEffect(() => {
const user = getUserLocalStorage();
console.log("USEEFFECT");
if (user) {
setUser(user);
}
}, [])
async function authenticate(
username:string,
password: string
) {
const response = await LoginRequest(username, password);
const payload = {token: response.token}; // <---- Problem on this line
setUser(payload);
setUserLocalStorage(payload);
}
function logout () {
setUser(null);
setUserLocalStorage(null);
}
return (
<AuthContext.Provider value={{...user, authenticate, logout}}>
{children}
</AuthContext.Provider>
)
}
Here is the LoginRequest code invoked in the code above. It could be that the problem is here:
import { Api } from "../../services/api";
import { IUser } from "./types";
export function setUserLocalStorage (user: IUser | null) {
localStorage.setItem('u', JSON.stringify(user));
}
export function getUserLocalStorage () {
const json = localStorage.getItem('u');
if (!json) {
return null;
}
const user = JSON.parse(json);
return user ?? null;
}
export async function LoginRequest (username: string, password: string) {
try {
console.log("AQUI");
const request = await Api.post(
'login/',
{username, password}
);
return request.data;
} catch (error) {
return null;
}
}
This is the code that posts the request:
import axios from "axios";
import { getUserLocalStorage } from "../context/AuthProvider/util";
export const Api = axios.create({
baseURL: "http://localhost:8000/",
});
Api.interceptors.request.use(
(config) => {
const user = getUserLocalStorage();
config.headers = {
Authorization: user?.token,
// Authorization: "Bearer " user?.token,
};
return config;
},
(error) => {
return Promise.reject(error);
}
);
What am I doing wrong?
Thanks!
CodePudding user response:
Typescript throws this error because your response has no type in it. First create an interface for your login response
Interface ILoginRequest {
token: string;
}
then type your post call in the loginRequest
const request = await Api.post<ILoginRequest>(
'login/',
{username, password}
);
that way request have the type AxiosResponse<ILoginResponse> this generic represents the data object inside the AxiosReponse.
as you returns request.data in your loginRequest function typescript should automatically type the return function of your method as ILoginResponse so
const response = await LoginRequest(username, password);
response will be of type ILoginRequest and now typescript won't throw more errors because it knows that response is an object which have a property token in it
