title: pass coordinates from googlemaps react child to parent in functional component typescript
body: <p>I'm using @googlemaps/react-wrapper to make a map component in my react application using the example from <a href="https://developers.google.com/maps/documentation/javascript/react-map" rel="nofollow noreferrer">googlemaps</a>, and adding an event on drag marker to refresh coordinates, this works fine now. but i need to call the map component outside to refresh a input value with the coordiantes.
  The error i get it is:</p>
  <blockquote>
  <p>Binding element 'childToParent' implicitly has an 'any' type.*
  Please could help me to understand how i could send the values to paren using typescript
  Greetings
  In parent i have this</p>
  </blockquote>
  <pre><code> const [coordinate,SetCoordinate]=useState(&quot;&quot;);  
  return (
          &lt;FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}&gt;
              &lt;Stack spacing={3}&gt;
  
                  &lt;RHFTextField name=&quot;lat&quot; label=&quot;Coord X&quot; /&gt;
                  &lt;RHFTextField name=&quot;lng&quot; label=&quot;Coord Y&quot; /&gt;
  
              &lt;/Stack&gt;
              &lt;Stack&gt;
                  &lt;br/&gt;
                  &lt;LocationMap  childToParent={setCoordinate}/&gt;
              &lt;/Stack&gt;
              &lt;Stack&gt;
  
                  &lt;LoadingButton
                      fullWidth
                      size=&quot;large&quot;
                      type=&quot;submit&quot;
                      variant=&quot;contained&quot;
                  &gt;
                      Save
                  &lt;/LoadingButton&gt;
              &lt;/Stack&gt;
          &lt;/FormProvider&gt;
      );
  </code></pre>
  <p>My Location map component is like this</p>
  <pre><code>const render = (status: Status) =&gt; {
    return &lt;h1&gt;{status}&lt;/h1&gt;;
  };
  interface MapProps extends google.maps.MapOptions {
    style: { [key: string]: string };
    onClick?: (e: google.maps.MapMouseEvent) =&gt; void;
    onIdle?: (map: google.maps.Map) =&gt; void;
  }
  //function to pass value to parent
  interface LocationProps {
    childToParent: (arg0: string)=&gt;string;
  }
  export default function LocationMap({childToParent,...props}){
  
    const [clicks, setClicks] = useState&lt;google.maps.LatLng[]&gt;([]);
    const [zoom, setZoom] = useState(3); // initial zoom
    const [center, setCenter] = useState&lt;google.maps.LatLngLiteral&gt;({
      lat: 0.0,
      lng: 0.0,
    });
    const [markerLocation, setMarkerLocation] = useState&lt;google.maps.LatLng&gt;();
    const dragend = (e: google.maps.MapMouseEvent) =&gt; {
      // avoid directly mutating state
      setMarkerLocation(e.latLng!)
      setClicks([...clicks, e.latLng!]);
  
    };
  
    const onClick = (e: google.maps.MapMouseEvent) =&gt; {
    };
    const onIdle = (m: google.maps.Map) =&gt; {
      //.log(&quot;onIdle&quot;);
      setZoom(m.getZoom()!);
      setCenter(m.getCenter()!.toJSON());
    };
  
    const ref = useRef&lt;HTMLDivElement&gt;(null);
    const [map, setMap] = useState&lt;google.maps.Map&gt;();
    useEffect(() =&gt; {
      if (ref.current &amp;&amp; !map) {
        setMap(new window.google.maps.Map(ref.current, {}));
      }
  
    }, [ref, map]);
  
    return (
      &lt;&gt;
        &lt;div style={{ display: &quot;flex&quot;, height: &quot;100%&quot; }}&gt;
          &lt;Wrapper apiKey={apiKey} render={render}&gt;
            &lt;Map
              center={center}
              onClick={onClick}
              onIdle={onIdle}
              zoom={zoom}
              style={{ flexGrow: &quot;1&quot;, height: &quot;25em&quot;, width: &quot;400px&quot; }}
            &gt;
  
  
              &lt;Marker key=&quot;point&quot; draggable={true} dragend={dragend} /&gt;
  
  
            &lt;/Map&gt;
  
          &lt;/Wrapper&gt;
        &lt;/div&gt;
        &lt;div id=&quot;coordinate&quot;&gt;
          {clicks.map(function (latLng, i, row) {
            var element = document.getElementById(&quot;coordenadas&quot;);
            if (element === null) {
              console.error(&quot;error cleaning coordinates&quot;);
            } else {
              element.innerHTML = &quot;&quot;;
            }
            return (
            childToParent(latLng.toJSON())
            );
          })
          }
        &lt;/div&gt;
      &lt;/&gt;
    )
  };
  
  interface MapProps extends google.maps.MapOptions {
    onClick?: (e: google.maps.MapMouseEvent) =&gt; void;
    onIdle?: (map: google.maps.Map) =&gt; void;
  }
  const Map: React.FC&lt;MapProps&gt; = ({
    onClick,
    onIdle,
    children,
    style,
    ...options
  }) =&gt; {
    const ref = useRef&lt;HTMLDivElement&gt;(null);
    const [map, setMap] = useState&lt;google.maps.Map&gt;();
  
    useEffect(() =&gt; {
      if (ref.current &amp;&amp; !map) {
        setMap(new window.google.maps.Map(ref.current, {}));
      }
    }, [ref, map]);
  
    // because React does not do deep comparisons, a custom hook is used
    // see discussion in https://github.com/googlemaps/js-samples/issues/946
    useDeepCompareEffectForMaps(() =&gt; {
      if (map) {
        map.setOptions(options);
      }
    }, [map, options]);
  
    useEffect(() =&gt; {
      if (map) {
        [&quot;click&quot;, &quot;idle&quot;].forEach((eventName) =&gt;
          google.maps.event.clearListeners(map, eventName)
        );
  
        if (onClick) {
          map.addListener(&quot;click&quot;, onClick);
        }
  
        if (onIdle) {
          map.addListener(&quot;idle&quot;, () =&gt; onIdle(map));
        }
      }
    }, [map, onClick, onIdle]);
  
    return (
      &lt;&gt;
        &lt;div ref={ref} style={style} /&gt;
        {Children.map(children, (child) =&gt; {
          if (isValidElement(child)) {
            // set the map prop on the child component
            return cloneElement(child, { map });
          }
        })}
      &lt;/&gt;
    );
  };
  interface MarkerProps extends google.maps.MarkerOptions {
    dragend?: (e: google.maps.MapMouseEvent) =&gt; void;
  }
  const Marker: React.FC&lt;MarkerProps&gt; = ({
    dragend,
    ...options
  }) =&gt; {
    const [marker, setMarker] = useState&lt;google.maps.Marker&gt;();
    console.log(options);
  
    useEffect(() =&gt; {
  
      if (!marker) {
        setMarker(new google.maps.Marker({
          position: {
            lat: 0,
            lng: 0,
          },
        }));
      }
  
      // remove marker from map on unmount
      return () =&gt; {
  
        if (marker) {
          marker.setMap(null);
        }
      };
    }, [marker]);
  
    useEffect(() =&gt; {
      if (marker) {
        marker.setOptions(options);
      }
    }, [marker, options]);
  
    useEffect(() =&gt; {
      if (marker) {
        [&quot;dragend&quot;].forEach((eventName) =&gt;
          google.maps.event.clearListeners(marker, eventName)
        );
        marker.setOptions(options);
        if (dragend) {
          //map.addListener(&quot;click&quot;, onClick);
          marker.addListener(&quot;dragend&quot;, dragend);
  
        }
      }
    }, [marker, dragend, options]);
  
    return null;
  };
  const deepCompareEqualsForMaps = createCustomEqual(
    (deepEqual) =&gt; (a: any, b: any) =&gt; {
      if (
        isLatLngLiteral(a) ||
        a instanceof google.maps.LatLng ||
        isLatLngLiteral(b) ||
        b instanceof google.maps.LatLng
      ) {
        return new google.maps.LatLng(a).equals(new google.maps.LatLng(b));
      }
  
      // TODO extend to other types
  
      // use fast-equals for other objects
      return deepEqual(a, b);
    }
  );
  
  function useDeepCompareMemoize(value: any) {
    const ref = useRef();
  
    if (!deepCompareEqualsForMaps(value, ref.current)) {
      ref.current = value;
    }
  
    return ref.current;
  }
  
  function useDeepCompareEffectForMaps(
    callback: React.EffectCallback,
    dependencies: any[]
  ) {
    useEffect(callback, dependencies.map(useDeepCompareMemoize));
  }
  export default LocationMap;
  </code></pre>