在 React 中使用 Mapbox 映射变量的正确类型是什么?

Rum*_*nsk 4 mapbox typescript reactjs mapbox-gl

在查看了mapbox文档后,我编写了这个组件

import React from "react";
import mapboxgl from "mapbox-gl";
import "./Map.css";

mapboxgl.accessToken = "...";

type Props = {
  longitude: number;
  latitude: number;
};

class Map extends React.Component<Props> {
  private mapContainer: any;
  private map: any;

  componentDidMount(): void {
    this.map = new mapboxgl.Map({
      container: this.mapContainer,
      center: [this.props.longitude, this.props.latitude],
      style: "....",
      zoom: 13
    });
  }
  render(): JSX.Element {
    return (
      <div
        ref={(el): void => {
          this.mapContainer = el;
        }}
        className="mapContainer"
      />
    );
  }
}

export default Map;
Run Code Online (Sandbox Code Playgroud)

这段代码可以正常工作,但是,在我的实际项目中,我们使用的是 TypeScript。我不想使用anyformapContainermap

我已导入"@types/mapbox-gl": "^1.7.0",到我的项目中,但我无法弄清楚我必须在这里使用什么类型。

到目前为止我的尝试:

  • private map:mapboxgl.Map。它似乎是正确的,但随后它会抱怨,因为它没有在构造函数上初始化。根据mapbox文档,它必须在componentDidMount. 我可以用 键入变量mapboxgl.Map | null。但随后我必须检查 constally 是否不为空,以删除一些烦人的警告。
  • private mapContainer = React.userRef<HtmlElement>(null);。但是,当我尝试初始化地图时,它显示“类型”'RefObject<HTMLElement>' is not assignable to type 'string | HTMLElement'.

有任何想法吗?

r3d*_*0rm 6

根据您的代码,以下内容有效。首先,您需要导入Map从中导出的类型mapbox-gl

import mapbox-gl, { Map } from "mapbox-gl";
Run Code Online (Sandbox Code Playgroud)

稍后可以将其用作组件内地图的类型:

private map: Map | undefined; // | undefined is needed here otherwise Typescript will complain about a missing initialiser inside the constructor.
Run Code Online (Sandbox Code Playgroud)

现在是棘手的部分,容器定义为:

container: string | HTMLElement
Run Code Online (Sandbox Code Playgroud)

在 MapboxOptions 类型定义中。因此我们必须稍微解决一下这个问题:

class SampleMap extends React.Component<Props> {
  private mapContainer: HTMLElement | null | undefined = undefined;
  private map: Map | undefined;

  componentDidMount(): void {
    this.map = new mapboxgl.Map({
      container:
        this.mapContainer === undefined || this.mapContainer === null
          ? "" // or pass in some other HTMLElement which is definitely defined or similar ...
          : this.mapContainer,
      ... // abbreviated
    });
  }
  render(): JSX.Element {
    ... // abbreviated
  }
}
Run Code Online (Sandbox Code Playgroud)

检查是否mapContainer已定义且不为空,然后传入mapContainer否则的 a string,或者也许您可以传入HTMLElement您知道 100% 已定义的其他值。例如document#root

完整的代码可以在这里找到:在 CodeSandbox 上