es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo retornar un tipo genérico en una función de flecha en React-TypeScript

Estoy intentando crear un hook personalizado en React. Todo funciona bien, pero ahora quiero agregar el tipo de retorno de mi respuesta, por lo que he convertido mi función de gancho en una función de flecha genérica de TypeScript. Ahora, cuando intento devolver este tipo genérico desde mis ganchos, obtengo un error dentro de mis ganchos.

El tipo ‘{ name: string; }’ no se puede asignar al tipo ‘T’.
‘T’ podría ser instanciado con un tipo arbitrario que podría no estar relacionado con ‘{ name: string; }’.

Gancho:

type httpRequest = {
  URL: string | undefined;
  Method: 'Get' | 'Post' | 'Put' | 'Delete';
  RequestBody: any;
};

type httpResponse<t> = {
  loading: boolean;
  data: T;
  error: any;
};

const useHttpRequest = <t>(request: httpRequest): httpResponse<t> => {
  console.log();

  return { loading: false, data: { name: 'Sabban' }, error: {} };
};

export default useHttpRequest;

Componente:

import React from 'react';
import useHttpRequest from '../hooks/use-http';

const Blog = () => {
  const httpRequest = useHttpRequest<{ name: string }>({
    URL: '',
    Method: 'Get',
    RequestBody: {},
  });

  return (
    <div classname="container">
      <div classname="card">
        <div classname="card-body">
          <h5 classname="card-title">Card title</h5>
          <h6 classname="card-subtitle mb-2 text-muted">Card subtitle</h6>
          <p classname="card-text">
            Some quick example text to build on the card title and make up the
            bulk of the card's content.
          </p>
        </div>
      </div>
    </div>
  );
};

export default Blog;

Solo quiero devolver el tipo exacto que obtengo del componente.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para devolver el tipo exacto que estás obteniendo del componente, debes asegurarte de que el tipo T en tu interfaz httpResponse sea asignable al tipo { name: string }. En la implementación actual de tu hook useHttpRequest, estás devolviendo { loading: false, data: { name: 'Sabban' }, error: {} }, lo cual no es asignable a { name: string }.

    Para solucionar este error, necesitas cambiar el valor de retorno de tu hook useHttpRequest para que coincida con el tipo T. Aquí tienes una forma de hacerlo:

    const useHttpRequest = <t>(request: httpRequest): httpResponse<t> => {
      const [loading, setLoading] = useState<boolean>(true);
      const [data, setData] = useState<t>();
      const [error, setError] = useState<any>();
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            setLoading(true);
            const response = await fetch(request.URL!, {
              method: request.Method,
              body: JSON.stringify(request.RequestBody),
              headers: {
                'Content-Type': 'application/json',
              },
            });
            const data = await response.json();
            setData(data);
            setLoading(false);
          } catch (error) {
            setError(error);
            setLoading(false);
          }
        };
    
        fetchData();
      }, [request.URL, request.Method, request.RequestBody]);
    
      return { loading, data, error };
    };
    

    En esta implementación, estamos usando los hooks useState y useEffect para gestionar el estado de los valores loading, data y error. También estamos obteniendo los datos de forma asíncrona utilizando la API fetch y convirtiendo la respuesta a JSON utilizando el método response.json().

    Con esta implementación, ahora puedes usar el hook useHttpRequest de la siguiente manera:

    const Blog = () => {
      const { loading, data, error } = useHttpRequest<{ name: string }>({
        URL: '',
        Method: 'Get',
        RequestBody: {},
      });
    
      if (loading) {
        return <div>Cargando...</div>;
      }
    
      if (error) {
        return <div>Error: {error.message}</div>;
      }
    
      return (
        <div>
          Nombre: {data.name}
        </div>
      );
    };
    

    En este componente, estamos utilizando los valores loading, data y error devueltos por el hook useHttpRequest para renderizar el componente condicionalmente. También estamos utilizando el valor data para acceder a la propiedad name y renderizarla en el componente.

Comments are closed.