ค้นหาเว็บไซต์

reactjs - Typescript และข้อผิดพลาดประเภทของ react-google-maps


ฉันเป็นมือใหม่กับ Typescript และสับสนมาก ฉันมีคอมโพเนนต์ที่ใช้ react-google-maps ซึ่งคอมโพเนนต์นี้สามารถนำกลับมาใช้ซ้ำได้

Map.tsx
import * as React from 'react';
import { compose, withStateHandlers } from 'recompose';
import { GoogleMap, withGoogleMap } from 'react-google-maps';

const ContactMap: React.ComponentClass<{}> = compose(
  withStateHandlers(() => ({
    isOpen: false,
    // tslint:disable-next-line:align
  }), {
      onToggleOpen: ({ isOpen }) => () => ({
        isOpen: !isOpen,
      }),
    }),
  withGoogleMap,
)(props =>
  <div>
    <GoogleMap
      defaultZoom={props.zoom}
      defaultCenter={props.center}
      defaultOptions={{
        streetViewControl: false,
        scaleControl: false,
        mapTypeControl: false,
        panControl: false,
        zoomControl: false,
        rotateControl: false,
        fullscreenControl: false,
        disableDefaultUI: true,
        scrollwheel: false,
      }}
    >
      {props.children}
    </GoogleMap>,
  </div>,
);

export default ContactMap;

และข้อผิดพลาดคือ: Property 'zoom' does not exist on type '{ children?: ReactNode; }'. และผมคิดว่ามันคงเกิดเหมือนกันกับ center

ฉันได้ลองอะไรประมาณนี้

interface Props {
  containerElement: any;
  mapElement: any;
  zoom: number;
  center: any;
}

และการส่งค่านั้นเข้ามา แต่สิ่งนั้นไม่สามารถแก้ปัญหาได้ มันจะส่งกลับ

Type 'ComponentClass<{}>' is not assignable to type 'ComponentClass<Props>'.
  Type '{}' is not assignable to type 'Props'.
    Property 'containerElement' is missing in type '{}'.

ส่วนประกอบของฉันที่ใช้แผนที่:

import * as React from 'react';
import { Map } from '@ecomm/map';
import { InfoWindow, Marker } from 'react-google-maps';

const ContactMap: React.SFC = () => {
  return (
    <Map
      containerElement={<div style={{ height: `400px` }} />}
      mapElement={<div style={{ height: `100%` }} />}
      center={{
        lat: 40.745093,
        lng: -73.993048,
      }}
      zoom={16}
    >
      <Marker
        position={{
          lat: 40.745093,
          lng: -73.993048,
        }}
      >
        <InfoWindow>
          <TextHeader>CHELSEA STUDIO</TextHeader>
        </InfoWindow>
      </Marker>
    </Map>
  );
};

export default ContactMap;

ฉันไม่แน่ใจว่าจะไปจากที่นี่อย่างไรและมันน่าหงุดหงิด ความช่วยเหลือใด ๆ จะได้รับการชื่นชม ขอบคุณ

คำตอบ #1

เพื่อแก้ปัญหาแบบของคุณ เป็นความคิดที่ดีที่จะตรวจสอบคำนิยามของฟังก์ชันที่คุณใช้ จากโค้ดตัวอย่างของคุณ ก็สามารถเดาได้ง่ายว่าปัญหาเกิดจากการใช้งาน compose เพราะมันเป็นฟังก์ชันที่รับคอมโพเนนต์หนึ่งและส่งคืนคอมโพเนนต์อีกตัว ด้วยความรู้นี้ เราสามารถไปที่ https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/recompose/index.d.ts หรือเช็คภายใน types ใน node_modules ของคุณ ที่นี่เรามี

export function compose<TInner, TOutter>(
     ...functions: Function[]
): ComponentEnhancer<TInner, TOutter>;

interface ComponentEnhancer<TInner, TOutter> {
     (component: Component<TInner>): ComponentClass<TOutter>;
}

ดังนั้นโดยพื้นฐานแล้วคุณสามารถส่งผ่านสองประเภทที่บอกว่า innerProps และ outerProps ของคุณคืออะไร

interface InnerProps {
  zoom: number;
  center: number[]; // it will not be available in ContactMap as prop
}
interface OuterProps {
  zoom: number;
}
const ContactMap = compose<InnerProps , OuterProps>(
  withStateHandlers(() => ({
    isOpen: false,
    // tslint:disable-next-line:align
  }), {
      onToggleOpen: ({ isOpen }) => () => ({
        isOpen: !isOpen,
      }),
    }),
  withGoogleMap,
)(props =>
  <div>
    <GoogleMap
      defaultZoom={props.zoom}
      defaultCenter={props.center}
      defaultOptions={{
        streetViewControl: false,
        scaleControl: false,
        mapTypeControl: false,
        panControl: false,
        zoomControl: false,
        rotateControl: false,
        fullscreenControl: false,
        disableDefaultUI: true,
        scrollwheel: false,
      }}
    >
      {props.children}
    </GoogleMap>,
  </div>,
);
...
<ContactMap  
   zoom={5}
   center={[1,3]} // error because it doesnt exist in OuterProps
/>

แน่นอนว่าคุณสามารถส่งพร็อพเหมือนกันสองครั้งได้ถ้าพร็อพนั้นเหมือนกัน compose<Props, Props>

คุณไม่จำเป็นต้องประกาศประเภทของตัวแปร const ContactMap: React.ComponentClass<{}> แบบนั้นเพราะ TS จะเลือกประเภทให้โดยอัตโนมัติจากผลลัพธ์ของฟังก์ชัน