How to create a GeoJSON Feature element using Typescript + react-leaflet
Asked Answered
D

4

6

I'm trying to create a <GeoJSON {...} /> react element from a Feature in Typescript, without success. (I'm using react-leaflet + Typescript) With regular js, I just have to do something like that:

<Map
    {...}
    <GeoJSON 
        data={...} <- Here I put my feature in JSON format
        style={...} <- Associated style
     />
/>

But in Typescript, if I try to do the exact same thing, I encounter the following error:

No overload matches this call.
  Overload 1 of 2, '(props: Readonly<GeoJSONProps>): GeoJSON<GeoJSONProps, GeoJSON<any>>', gave the following error.
    Type '{ type: string; geometry: { type: string; coordinates: number[]; }; }' is not assignable to type 'GeoJsonObject'.
      Object literal may only specify known properties, and 'geometry' does not exist in type 'GeoJsonObject'.
  Overload 2 of 2, '(props: GeoJSONProps, context?: any): GeoJSON<GeoJSONProps, GeoJSON<any>>', gave the following error.
    Type '{ type: string; geometry: { type: string; coordinates: number[]; }; }' is not assignable to type 'GeoJsonObject'.
      Object literal may only specify known properties, and 'geometry' does not exist in type 'GeoJsonObject'.ts(2769)

Here is a sample of the many things I tried:

<Map
    {...}
    <GeoJSON
        data={{
            type: "Feature",
            geometry: {
                type: "Point",
                coordinates: [125.6, 10.1]
            }
        }}
    />
/>

When I check the GeoJsonObject type definition, geometry does not exists, there is just the "type" field, so how am I supposed to pass the geometry to the GeoJSON element I'm trying to create ? (type definition of GeoJsonObject: http://definitelytyped.org/docs/geojson--geojson/interfaces/geojson.geojsonobject.html )

And if I try this code in "regular" javascript, it does work, do you know why ?

Downthrow answered 22/2, 2020 at 6:11 Comment(1)
Any news for this issue ?Castled
D
5

Solution 1 (recommended)

Use the correct type for the GeoJson object you are interested in.

import { GeoJSON } from 'react-leaflet';

const data: GeoJSON.Feature = {
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [125.6, 10.1],
    },
    properties: {},
};

<Map
    {...}
    <GeoJSON data={data} />
/>

Solution 2 (not recommended)

Tell the Typescript compiler that it should treat the object as of type GeoJsonObject.

import { GeoJsonObject } from 'geojson';

<Map
    {...}
    <GeoJSON
        data={{
            type: "Feature",
            geometry: {
                type: "Point",
                coordinates: [125.6, 10.1]
            }
        } as GeoJsonObject }
    />
/>
Downspout answered 2/2, 2022 at 10:32 Comment(0)
D
-1

I think the error is on the code and typing of the GeoJSON component. It looks as if that component expects a GeoJsonObject and does not accept the Feature. You could try changing the type of the data property to Feature<Point> and check if that error goes away.

Duct answered 22/2, 2020 at 8:30 Comment(0)
G
-1

There are a couple of things happening here.

First, according to the @types/geojson type definitions, a point Feature needs to have a type field set to a string literal type of "Feature" (and the geometry object is defined to have a type field with a string literal type of "Point").

Second, the TypeScript compiler isn't able to infer that the "type" fields have the correct string literal type (it infers they are instead of the more general type "string"). A good explanation for this sort of thing can be found in this answer to the question "Typescript - Why can't this string literal type be inferred?".

Now that we understand the problem, we can fix it. Here's your example modified in a way that should work:

<Map
    {...}
    <GeoJSON
        data={{
            type: "Feature" as "Feature",
            geometry: {
                type: "Point" as "Point",
                coordinates: [125.6, 10.1]
            }
        }}
    />
/>

The only difference is the addition of the two type assertions as "Feature" and as "Point" which tell the TypeScript compiler these "type:" fields have the string literal types of "Feature" and "Point", respectively.

To reduce duplication, you can also use as const instead of as "Feature" etc.

Gritty answered 29/4, 2020 at 0:27 Comment(0)
G
-1

Very probably you just miss the properties member (possibly an empty object) of your GeoJSON Feature object(s): http://definitelytyped.org/docs/geojson--geojson/interfaces/geojson.feature.html

{
  type: "Feature",
  geometry: {
    type: "Point",
    coordinates: [125.6, 10.1]
  },
  properties: {} // Not optional for a Feature
}
Graphic answered 29/4, 2020 at 2:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.