Pesquisa de site

reactjs - Por que o Source do react-map-gl não está usando um objeto?


Estou tentando adicionar geoJSON em um mapa react-map-gl usando TypeScript

aqui está meu código

<Source id="my-data" type="geojson" data={data}>
    <Layer {...layerStyles}/>
</Source>

a variável data é um arquivo JSON analisado, então é um objeto, não

o erro que recebo é

 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}

E o tipo das props de dados no componente Source deve ser um objeto, como você pode ver na documentação https://visgl.github.io/react-map-gl/docs/api-reference/source

se você precisar de mais informações, por favor pergunte

Resposta #1

Explicação

Vamos analisar este erro:

Overload 1 of 2, '(props: SourceProps | Readonly<SourceProps>): Source'
...
Overload 2 of 2, '(props: SourceProps, context: any): Source

No nível superior, ele está mostrando as duas maneiras possíveis de usar o componente Source. Supondo que você não esteja atribuindo um context, vamos continuar olhando para a Sobrecarga 1

Type 'object' is not assignable to type 'string | Feature<Geometry, GeoJsonProperties> | FeatureCollection<Geometry, GeoJsonProperties> | undefined'.

Isso nos diz que o TypeScript acha que data é um object, mas ele espera que seja especificamente uma string ou um Feature ou um FeatureCollection (especificamente features de Geometry, GeoJsonProperties)
Isso nos diz que object não é um tipo específico o suficiente para satisfazer o compilador.

Type '{}' is missing the following properties from type 'FeatureCollection<Geometry, GeoJsonProperties>': type, features

Aqui está tentando ser útil ao nos dizer o que falta no tipo object. Observe que ele reduziu seu tipo para um objeto vazio sem propriedades.

Solução

Então, como você diz ao compilador o que é data?
Vou assumir que você está buscando os dados e, portanto, o TypeScript não consegue inferir seu tipo automaticamente

Opção 1 - use um guarda de tipo para verificar os dados recebidos

function isFeatureCollection(data: unknown): data is FeatureCollection<Geometry, GeoJsonProperties> {
    return (
        typeof data === 'object'
        && data !== null
        && 'type' in data
        && 'features' in data
    );
}

Então use o guardião de tipo para sair da renderização, e o TypeScript saberá que após essa verificação que data terá o tipo esperado por Source

if (!isFeatureCollection(data)) return null;

<Source id="my-data" type="geojson" data={data}>
    <Layer {...layerStyles}/>
</Source>

Opção 2 - Converta o tipo usando as para o que você espera que seja:

const data = await getData() as FeatureCollection<Geometry, GeoJsonProperties>;

Isso não é recomendado, pois você está descartando a garantia de tipos do Typescript aqui

Artigos relacionados