Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting TS Error: Property 'user' does not exist on type 'IAuth | null'

I am using context for Auth in my simple typescript app. My context declaration is in the file AuthProvider.tsx, which looks like:

import React, { createContext, useState } from 'react';
import auth from '@react-native-firebase/auth';

export interface IAuth {
    user,
    setUser,
    login,
    register,
    logout
}

export const AuthContext = createContext<IAuth | null>(null);

export const AuthProvider = ({ children }) => {
    const [user, setUser] = useState(null);

    return (
        <AuthContext.Provider
            value={{
                user: user,
                setUser: setUser,
                login: async (email, password) => {
                    try {
                        await auth().signInWithEmailAndPassword(email, password);
                    } catch (e) {
                        console.log(e);
                    }
                },
                register: async (email, password) => {
                    try {
                        await auth().createUserWithEmailAndPassword(email, password);
                    } catch (e) {
                        console.log(e);
                    }
                },
                logout: async () => {
                    try {
                        await auth().signOut();
                    } catch (e) {
                        console.log(e);
                    }
                },
            }}>
            {children}
        </AuthContext.Provider>
    );
};

This is how I am using it elsewhere:

  const { user, setUser } = useContext(AuthContext);

But Typescript throws 2 errors on this lien:

  1. Property 'user' does not exist on type 'IAuth | null'
  2. Property 'setUser' does not exist on type 'IAuth | null'

What can I do to bypass it?

like image 928
Karan Singh Avatar asked Aug 31 '25 21:08

Karan Singh


2 Answers

Right here, you have said that contents of your AuthContext can be either an IAuth object or it can be null.

export const AuthContext = createContext<IAuth | null>(null);

You cannot destructure the value of useContext(AuthContext) as if it were an object because you have not verified that it is an actually an IAuth and not null.

There are many ways to address this.

One approach is that you can still allow for the context value to be null, but we have to check before using it. This works and is easy to implement. We can exit the component early by returning null if the values don't exist. But you must make sure that you exit only after all other hooks have been called or else you'll get a "violated the rules of hooks" error.

export const Consumer = () => {
   const context = useContext(AuthContext);
   if ( ! context ) {
     return null;
   }
   const { user, setUser } = context;

   return (
     <div/>
   )
}

Another approach is that we allow for an empty or incomplete object instead of null. This allows us to destructure, but we are just moving the errors down the chain because those two value that we destructured user and setUser might have the expected values or might be undefined.

export const AuthContext = createContext<Partial<IAuth>>({});
const { user, setUser } = useContext(AuthContext);

A more verbose approach is to create a default value for the context which fulfills the IAuth interface by using dummy methods. These functions should be callable so that won't produce errors but they don't do anything.

const defaultValue: IAuth = {
  setUser: () => console.error("attempting to use AuthContext outside of a valid provider"),
  /*... */
}

export const AuthContext = createContext<IAuth>(defaultValue);

Does your interface really look like what you've posted, or did you just remove the values for the sake of the question? An interface needs to define the type associated with each key, not just list the keys.

like image 187
Linda Paiste Avatar answered Sep 03 '25 10:09

Linda Paiste


I guess you can cast it to IAuth with const { user, setUser } = useContext(AuthContext) as IAuth

like image 41
Adithya Avatar answered Sep 03 '25 12:09

Adithya