为什么 react-map-gl Source 不使用对象?

Why is the react-map-gl Source not using an object?

我正在尝试使用 typescript

将 geoJSON 添加到 react-map-gl 地图中

这是我的代码

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

data 变量是一个已解析的 JSON 文件,因此它不是一个对象

我得到的错误是

 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}

并且 Source 组件中的数据属性类型应该是一个对象,正如您从文档中看到的那样 https://visgl.github.io/react-map-gl/docs/api-reference/source

如果您需要更多信息,请询问

说明

让我们来分析一下这个错误:

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

在顶层,它显示了您可以使用 Source 组件的两种可能方式。假设您没有给它分配 context,让我们继续看一下 Overload 1

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

这告诉我们打字稿认为 data 是一个 object,但它期望它具体是 stringFeatureFeatureCollectionGeometry, GeoJsonProperties的具体特征)
这告诉我们 object 的类型不够具体,无法满足编译器的要求。

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

它试图通过告诉我们 object 类型中缺少什么来提供帮助。请注意,它将您的类型减少为没有属性的空对象。

解决方案

那么你如何告诉编译器 data 是什么?
我将假设您正在获取数据,因此打字稿无法自动推断其类型

选项 1 - 使用类型保护检查传入数据

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

然后使用类型保护退出渲染,打字稿将知道在检查之后 data 将是 Source

期望的类型
if (!isFeatureCollection(data)) return null;

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

选项 2 - 使用 as 将类型转换为您期望的类型:

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

不推荐这样做,因为您在这里丢弃了 Typescript 的类型保证