I'm currently learning Typescript and moving all the code of my project with Type Safety from Typescript but I still don't understand certain things like this one.
I am only trying to correctly type everything and trying to understand the process of how they work so.
This is my AuthContext.tsx file which exports the value of the currentUser easily for me throughout the React app
import React, { createContext, useEffect, useState } from 'react';
import { onAuthStateChanged, User } from 'firebase/auth';
import { auth } from '../firebase.config';
type Props = {
children?: React.ReactNode;
};
type TAuthValue = {
currentUser: User | null;
};
interface TAuthContext extends TAuthValue {
(): JSX.Element;
}
export const AuthContextProvider = ({ children }: Props) => {
const [currentUser, setCurrentUser] = useState<User | null>(null);
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setCurrentUser(user);
});
return () => {
unsub();
};
}, []);
return <UserContext.Provider value={{ currentUser }}>{children}</UserContext.Provider>;
};
export const UserContext = createContext<TAuthContext>(AuthContextProvider);
The errors I receive when attempting to do it this way is:
ERROR in src/context/AuthContext.tsx:29:34
TS2322: Type '{ currentUser: User | null; }' is not assignable to type 'TAuthContext'.
Type '{ currentUser: User | null; }' provides no match for the signature '(): Element'.
27 | }, []);
28 |
> 29 | return <UserContext.Provider value={{ currentUser }}>{children}</UserContext.Provider>;
| ^^^^^
30 | };
31 |
32 | export const UserContext = createContext<TAuthContext>(AuthContextProvider);
ERROR in src/context/AuthContext.tsx:32:56
TS2345: Argument of type '({ children }: Props) => JSX.Element' is not assignable to parameter of type 'TAuthContext'.
Property 'currentUser' is missing in type '({ children }: Props) => JSX.Element' but required in type 'TAuthContext'.
30 | };
31 |
> 32 | export const UserContext = createContext<TAuthContext>(AuthContextProvider);
| ^^^^^^^^^^^^^^^^^^^
33 |
I have tried reversing which type/interface extends which but they still provide errors. I looked at the documentation but I still am not sure what I'm doing wrong. Any guidance or pointers on where to look or an explanation would be greatly appreciated!
CodePudding user response:
You're passing an entire component to createContext
. But while using the context, you're passing it currentUser
in the value
prop.
currentUser
is of type User | null
. Your context is of type (): JSX.Element
which clearly have no overlap. Ideally, your UserContext
should be of type User | null
Check the docs on how to use Context
export const UserContext = createContext<User | null>(null);