Reputation: 47
I'm trying to add geoJSON into a react-map-gl map using typescript
here is my code
<Source id="my-data" type="geojson" data={data}>
<Layer {...layerStyles}/>
</Source>
the data
variable is a parsed JSON file so it is an object not
the error I get is
Overload 1 of 2, '(props: SourceProps | Readonly<SourceProps>): Source', gave the following error.
Type 'object' is not assignable to type 'string | Feature<Geometry, GeoJsonProperties> | FeatureCollection<Geometry, GeoJsonProperties> | undefined'.
Type '{}' is missing the following properties from type 'FeatureCollection<Geometry, GeoJsonProperties>': type, features
Overload 2 of 2, '(props: SourceProps, context: any): Source', gave the following error.
Type 'object' is not assignable to type 'string | Feature<Geometry, GeoJsonProperties> | FeatureCollection<Geometry, GeoJsonProperties> | undefined'. TS2769
123 | onViewportChange={(nextView:typeof viewport) => setViewport(nextView)}>
124 | {/* GeoJSON */}
> 125 | <Source id="my-data" type="geojson" data={data}>
| ^
126 | <Layer {...layerStyles}/>
127 | </Source>
128 | {markers}
And the type of the data props in the Source component is supposed to be an object as you can see from the documentation https://visgl.github.io/react-map-gl/docs/api-reference/source
if you need any more information please ask
Upvotes: 3
Views: 1189
Reputation: 5671
Let's pull apart this error:
Overload 1 of 2, '(props: SourceProps | Readonly<SourceProps>): Source'
...
Overload 2 of 2, '(props: SourceProps, context: any): Source
At the top level it is showing the two possible ways that you can use the Source
component. Assuming you aren't assigning it a context
, let's continue looking at Overload 1
Type 'object' is not assignable to type 'string | Feature<Geometry, GeoJsonProperties> | FeatureCollection<Geometry, GeoJsonProperties> | undefined'.
This is telling us that typescript thinks data
is an object
, but it's expecting it to be specifically a string
or a Feature
or a FeatureCollection
(specifically features of Geometry, GeoJsonProperties
)
This tells us that object
is not a specific enough type to satisfy the compiler.
Type '{}' is missing the following properties from type 'FeatureCollection<Geometry, GeoJsonProperties>': type, features
Here's it's trying to be helpful by telling us what's missing in the object
type. Note that it's reduced your type to an empty object without properties.
So how do you tell the compiler what data
is?
I'm going to assume that you are fetching the data and so typescript is unable to infer it's type automatically
Option 1 - use a type guard to check the incoming data
function isFeatureCollection(data: unknown): data is FeatureCollection<Geometry, GeoJsonProperties> {
return (
typeof data === 'object'
&& data !== null
&& 'type' in data
&& 'features' in data
);
}
Then use the type guard to exit out of the render, and typescript will know that after this check that data
will be the type expected by Source
if (!isFeatureCollection(data)) return null;
<Source id="my-data" type="geojson" data={data}>
<Layer {...layerStyles}/>
</Source>
Option 2 - Cast the type using as
to what you expect it to be:
const data = await getData() as FeatureCollection<Geometry, GeoJsonProperties>;
This isn't recommended as you're throwing away Typescript's type guarantee here
Upvotes: 4