为啥 react-map-gl Source 不使用对象?
Posted
技术标签:
【中文标题】为啥 react-map-gl Source 不使用对象?【英文标题】:Why is the react-map-gl Source not using an object?为什么 react-map-gl Source 不使用对象? 【发布时间】:2022-01-11 08:15:03 【问题描述】:我正在尝试使用 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 组件中的数据 props 的类型应该是一个对象,如您从文档 https://visgl.github.io/react-map-gl/docs/api-reference/source 中看到的那样
如果您需要更多信息,请询问
【问题讨论】:
在这种情况下data
是什么?
这是一个 JSON 文件,包含我导入的所有 geoJSON 然后解析成一个对象,它是一个包含 geoJSON 的对象吗
当它到达此代码时,您是否验证了形状是正确的?显然Source
组件不同意并认为data
缺少名为type
和features
的属性。
是的,数据既有类型又有特性,我可以对它们进行控制台记录。
你能在这里分享吗?
【参考方案1】:
说明
让我们分解这个错误:
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'.
这告诉我们 typescript 认为 data
是 object
,但它期望它具体是 string
或 Feature
或 FeatureCollection
(特别是 Geometry, 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 的类型保证
【讨论】:
以上是关于为啥 react-map-gl Source 不使用对象?的主要内容,如果未能解决你的问题,请参考以下文章
我可以像在(mapbox-gl-js 文档)中那样使用 react-map-gl 添加 GeoJSON 行吗?
为啥 TargetNullValue 更新可为空的 Source