3

I just get started in Typescript. I seen a lot of example and question about custom hooks, but I still cant figure out due to my file structure is different with other example.

Background:

I have this 1 file named useAuth.tsx which have the structure like this:

const defaultValue = { // Here I make this temporary 1st 
  
};

const AuthContext = createContext(defaultValue)

const AuthContextProvider = (props: AuthContextProviderProps) => {
  const auth = useFirebaseAuth(); // this will use value from the hook below

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

export default function useFirebaseAuth() {
  const [user, setUser] = useState<UserDetails | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  const loginWithEmailPassword = (email: string, password: string) => {
    //... stuff
  }

  const signUpWithEmailPassword = (email: string, password: string) => {
    //... stuff
  }

  return {
    user,
    isLoading,
    errorMessage,
    loginWithEmailPassword,
    signUpWithEmailPassword,
  };

}

**Problems:** 

So when I use this useAuth() hooks in another file, named Login.tsx like this:

const { user } = useAuth(); 

I will get this error:

Property 'user' does not exist on type '{}'.ts(2339)

My Attempts:

From my understanding, the problems is cause by user is not defined in useAuth(), therefore TypeScript doesn't know that user is existed inside useAuth

Here is what I have tried:

interface UserData {
 id: ... //etc 

}

// here define an interface for all the return value 
interface AuthContextInterface {  
  user: UserData | null;
  loginWithEmailPassword: (email: string, password: string )=> void;
  signUpWithEmailPassword: (email: string, password: string )=> void;
  isLoading: boolean;
  errorMessage: string | null;
}


// then use it here as  a type of createContext 
const AuthContext = createContext<AuthContextInterface>(defaultValue)

At this point I will get this problem at defaultValue :

Type '{}' is missing the following properties from type 'AuthContextInterface': user, loginWithEmailPassword, signUpWithEmailPassword, isLoading, errorMessage

So I have to define the value inside defaultValue as well:

const defaultValue = {
  
  user:null,
  isLoading: false,
  errorMessage: null,
  
  loginWithEmailPassword:() => void, // this is the problem, what should I put here as default value 
  signUpWithEmailPassword: () => void, 
};

Others value is not problem, but loginWithEmailPassword and signUpWithEmailPassword is a function, so as a default value what should I state, since it not exist yet?

Please give some advise. Tq

1 Answer 1

4

try defining an empty object to defaultValue:

const defaultValue = {};

and create the context forcing the typescript to understand the defaultvalue as the interface

const AuthContext = createContext<AuthContextInterface>(defaultValue as AuthContextInterface);

if you are not using eslint, you can also do this

const AuthContext = createContext<AuthContextInterface>(defaultValue as any);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.