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
