我不知道如何将 Typescript 添加到我的 React useState 挂钩中,我做错了什么?

I can't figure out how to add Typescript to my React useState hooks, what am I doing wrong?

我在将 Typescript 添加到我的 React 代码时遇到了很多问题,特别是在使用 useSate 挂钩时。

过去几天我一直在研究如何解决这个问题,但我不确定需要将什么传递到挂钩中。我应该创建一个单独的 .ts 文件来存储我在挂钩中期望的内容吗?当我滚动带下划线的错误时,它一直显示如下错误:

Argument of type 'Map' is not assignable to parameter of type 'SetStateAction'. Type 'Map' provides no match for the signature '(prevState: undefined): undefined'.

Property 'features' does not exist on type '{ children?: ReactNode; }'.`

我已经包含了我的代码以提供更好的视角,并在评论中留下了我正在使用的来源。

import { FC } from "react";
import { useState, useEffect, useRef } from "react";
import "./mapwrapper.css";

// openlayers
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import XYZ from "ol/source/XYZ"; //here...

import { fromLonLat } from "ol/proj";

const Home: FC<{}> = (props) => {
  // set intial state
  const [map, setMap] = useState();
  const [featuresLayer, setFeaturesLayer] = useState();

  // pull refs
  const mapElement = useRef<HTMLDivElement>(null);

  // create state ref that can be accessed in OpenLayers onclick callback function
  //  
  const mapRef = useRef<{}>();
  mapRef.current = map;

  // initialize map on first render - logic formerly put into componentDidMount
  useEffect(() => {
    // create and add vector source layer
    const initalFeaturesLayer = new VectorLayer({
      source: new VectorSource(),
    });

    const seoul = [126.97794, 37.56629];
    const seoulWebMercator = fromLonLat(seoul);

    // create map
    const initialMap = new Map({
      target: mapElement.current!,
      layers: [

        // Google Maps Terrain
        new TileLayer({
          source: new XYZ({
            url: "http://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}",
          }),
        }),

        initalFeaturesLayer,
      ],
      view: new View({
        projection: "EPSG:3857",
        center: seoulWebMercator,
        zoom: 16,
      }),
      controls: [],
    });

    // save map and vector layer references to state
    setMap(initialMap);
    setFeaturesLayer(initalFeaturesLayer);
  }, []);

  // update map if features prop changes - logic formerly put into componentDidUpdate
  useEffect(() => {
    if (props.features.length) {
      // may be null on first render

      // set features to map
      featuresLayer.setSource(
        new VectorSource({
          features: props.features, // make sure features is an array
        })
      );

      // fit map to feature extent (with 100px of padding)
      map.getView().fit(featuresLayer.getSource().getExtent(), {
        padding: [100, 100, 100, 100],
      });
    }
  }, [props.features, featuresLayer, map]);


  return (
    <div>
      <div ref={mapElement} className="map-container"></div>

    </div>
  );
};

export default Home;

在 TypeScript 中,您需要声明所有类型,包括对象类型中的所有属性。

从您提供的错误信息来看,这两个错误是因为您没有声明正确的类型。

Argument of type 'Map' is not assignable to parameter of type 'SetStateAction'. Type 'Map' provides no match for the signature '(prevState: undefined): undefined'.

这个错误是因为你没有为useState声明类型,所以默认为undefined。您可以通过执行以下操作轻松修复它:

// You should substitute `any` type to a more appropriate type.
const [map, setMap] = useState<Map<any, any>>();

Property 'features' does not exist on type '{ children?: ReactNode; }'.`

这个错误是因为你没有在组件props的类型中声明需要的属性

type HomeProps = {
  // You should substitute `any` type to a more appropriate type.
  features: any;
};

const Home: FC<HomeProps> = (props) => {
  ...
}

可能还有更多类似的错误是您没有正确声明类型。您需要做的就是声明它们。

对于地图问题,您应该明确提供类型

const [map, setMap] = useState<Map>();

对于feature和featureLayer的问题,你应该提供道具类型

type HomeProps = { features: any[] };

const Home: FC<HomeProps> = (props) => {

 const [map, setMap] = useState<Map>();
 const [featuresLayer, setFeaturesLayer] = useState<
    VectorLayer<VectorSource<Geometry>>
 >();


 ...

 useEffect(() => {
    if (props.features?.length && featuresLayer) {
    ...
    }
 }, [props.features, featuresLayer, map]);
  
}

这是codesandbox for demo