Búsqueda de sitios web

reactjs - Valor predeterminado de la interfaz TypeScript cuando una propiedad es de tipo función para los hooks useContext


Acabo de empezar en Typescript. He visto muchos ejemplos y preguntas sobre hooks personalizados, pero todavía no puedo entenderlo debido a que mi estructura de archivos es diferente de otros ejemplos.

Antecedentes:

Tengo este 1 archivo llamado useAuth.tsx que tiene la siguiente estructura:

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:** 

Entonces, cuando uso este hook useAuth() en otro archivo, llamado Login.tsx, de esta manera:

const { user } = useAuth(); 

Obteneré este error:

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

Mis Intentos:

Según mi entendimiento, el problema es causado porque user no está definido en useAuth(), por lo tanto TypeScript no sabe que user existe dentro de useAuth

Esto es lo que he intentado:

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)

En este punto obtendré este problema en defaultValue :

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

Así que también tengo que definir el valor dentro de defaultValue:

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

El valor de otros no es un problema, pero loginWithEmailPassword y signUpWithEmailPassword son funciones, entonces, como valor por defecto, ¿qué debería indicar, dado que aún no existen?

Por favor, da algún consejo. Gracias

Respuesta #1

intenta definir un objeto vacío como valor predeterminado:

const defaultValue = {};

y crear el contexto obligando a TypeScript a entender el valor predeterminado como la interfaz

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

si no estás usando eslint, también puedes hacer esto

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

Artículos relacionados