ng-someone
ng-someone

Reputation: 501

Google Maps React - No overload matches this call

I'm getting this error when trying to run my app

TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '{ map: google.maps.Map | undefined; }' is not assignable to parameter of type 'Partial<unknown> & Attributes'.
      Object literal may only specify known properties, and 'map' does not exist in type 'Partial<unknown> & Attributes'.
    60 |                        {React.Children.map(children, (child) => {
    61 |                                if (React.isValidElement(child)) {
  > 62 |                                        return React.cloneElement(child, { map });
       |                                                                           ^^^
    63 |                                }
    64 |                        })}
    65 |                </>

In my package.json I have installed the "@types/google.maps": "^3.49.2" and "@types/google.maps": "^3.49.2"

The map itself was working just right, but then this happened. I don't know where this error is coming from, please help.

The map component:

const MapComponent = ({ children, style, zoom = 8, lat, lng }: MapProps) => {
    const ref = useRef<HTMLDivElement>(null);
    const [map, setMap] = useState<google.maps.Map>();

    useEffect(() => {
        if (ref.current && !map) {
            setMap(
                new window.google.maps.Map(ref.current, {
                    zoom,
                    center: {
                        lat,
                        lng,
                    },
                })
            );
        }
    }, [ref, map]);

    return (
        <>
            <div ref={ref} style={style} />
            {React.Children.map(children, (child) => {
                if (React.isValidElement(child)) {
                    return React.cloneElement(child, { map });
                }
            })}
        </>
    );
};

const Map = ({
    className = '',
    height = 22,
    zoom = 8,
    latitude = 30,
    longitude = -180,
    markerLat,
    markerLng,
}: Props): JSX.Element => {
    return (
        <div
            data-testid="contact-card"
            className={`w-fill rounded-lg border border-gray-border ${className}`}
            style={{ height: `${height}rem` }}
        >
            <Wrapper apiKey={EnvironmentVariables.GOOGLE_MAPS} render={render}>
                <MapComponent
                    style={{ flexGrow: '1', height: '100%' }}
                    lat={latitude}
                    lng={longitude}
                    zoom={zoom}
                >
                    {markerLat && markerLng && (
                        <Marker position={{ lat: markerLat, lng: markerLng }} />
                    )}
                </MapComponent>
            </Wrapper>
        </div>
    );
};

Stackoverflow doesnt allow me to show the full code due to the size of the code. But here is an example of I did it

Upvotes: 2

Views: 985

Answers (2)

ng-someone
ng-someone

Reputation: 501

Actually, what solved my problem was changing the map useState type and returning the React.cloneElement(child) as a React element.

    const [map, setMap] = useState<google.maps.Map & Partial<unknown>>();

And on the MapComponent return ...

            {React.Children.map(children, (child) => {
                if (React.isValidElement(child)) {
                    return React.cloneElement(child as React.ReactElement<any>, { map });
                }
            })}

Upvotes: 0

KennyC
KennyC

Reputation: 61

Doing exactly same thing, just figure it out five minutes ago.

Basically I follow doc from google, of course it doesn't work, I change declaration of MapProps to this

interface MapProps extends google.maps.MapOptions {
    style: { [key: string]: string };
    onClick?: (e: google.maps.MapMouseEvent) => void;
    onIdle?: (map: google.maps.Map) => void;
    children?: React.ReactElement<google.maps.MarkerOptions>;
}

with code above, type of cloneElement will change from undefined to google.maps.MarkerOptions, the reason I did this is the second parameter of cloneElement is Partial, and we want to change the map parameter of MarkerOptions.

if the there will be single or multiple child, can try this

children?: React.ReactElement<google.maps.MarkerOptions>[] | React.ReactElement<google.maps.MarkerOptions>

Upvotes: 2

Related Questions