When accessing a React context with TypeScript, you may encounter an error stating that a property does not exist on the type. This typically occurs when TypeScript cannot infer the precise type of the context object. To resolve this, you can either use type assertions to explicitly specify the type of the context object, or utilize a custom hook that encapsulates the context logic and ensures type safety, such as useAppContext
. This approach enhances code clarity and maintainability while addressing TypeScript’s type inference limitations.
How to reproduce it
// app-context.ts
export const AppContext = createContext<IAppContext | null>(null);
// Component.tsx
const { appData, setAppData } = useContext(AppContext);
Errors
Property 'appData' does not exist on type 'IAppContext | null'.
Property 'setAppData' does not exist on type 'IAppContext | null'.
Solution #1
When you directly use useContext(AppContext)
, TypeScript cannot determine the exact type of the context object (IAppContext
) and defaults to IAppContext | null
. As a result, it complains that appData
and setAppData
do not exist on IAppContext | null
.
To fix this error you can use type assertions to tell TypeScript the exact type of AppContext
.
const { appData, setAppData } = useContext(AppContext) as IAppContext;
Solution #2
You can define a custom hook called “useAppContext
“, where you explicitly specify the return type of the hook as IAppContext
. This tells TypeScript that the context object returned by the hook will always have the structure defined by IAppContext
, avoiding the error.
To fix this error create a custom hook useAppContext
to conveniently consume the context within components.
app-context.ts
export const useAppContext = () => {
const context = useContext(AppContext);
if (!context) {
throw new Error("useAppContext must be used within an AppContextProvider");
}
return context;
};
Component.tsx
const { appData, setAppData } = useAppContext();