Hur man fixar Typescript-fel med något exempel på reactjs-popup-kod


Följande kod (hämtad från reactjs-popup-dokumentationen) ger Typescript-felet Type '(close: any) => Element' is not assignable to type 'ReactNode'.ts(2322) när man använder reactjs-popup-komponenten. Finns det något sätt att åtgärda detta fel utan att använda "@ts-ignore"?

import React from 'react';
import Popup from 'reactjs-popup';

const mypopup = () => (
  <div>
    <Popup
      trigger={<button>Information</button>}
      modal
    >
      {close => (
        <div>
          <div>What is this?</div>
          <button onClick={() => { close(); }}>close</button>
        </div>
      )
      }
    </Popup>
  </div>
);

Svar #1

Grattis, du stötte på ett problem som inte är ditt fel! Detta är en förbiseende i typerna för reactjs-popup-paketet.

Du definierar barnet till Popup som en funktion. Detta stöds av biblioteket och finns med i deras dokumentation, som visar användningen av "funktion som barn-mönster".

Men när du tittar på deras TypeScript-typer täcks inte denna typ av användning. children-egenskapen hos Popup definieras som:

  children: React.ReactNode;

  //| ((close: () => void, isOpen: boolean) => React.ReactNode);

Den typ du behöver finns i deras källkod, men den är utkommenterad?! Mycket märkligt. Som det är nu säger typerna att children av Popup endast kan vara en ReactNode och inte kan vara en funktion.

Du bör öppna ett ärende i deras repo för att rapportera detta misstag. De har en stor banner som säger att paketet söker underhållare, så jag skulle inte förvänta mig att det blir fixat inom den närmaste tiden.

Svar #2

Popup-komponenten förväntar sig att ha barn som React.ReactNode, medan den borde förvänta sig antingen en callback-funktion (som illustreras i ditt användningsfall). En snabb lösning skulle vara att @ts-ignore, som du föreslog, men naturligtvis vill du fortfarande ha typsäkerhet.

I så fall, för att få komponenten att fungera igen, kan du omsluta den i en egen komponent, där du omdeklarerar props för att förvänta sig rätt typ.

import { Popup } from "reactjs-popup";
import type { PopupProps } from "reactjs-popup/dist/types";
import "./App.css";

type MyPopupProps = {
  children: React.ReactNode | ((close: () => void, isOpen: boolean) => React.ReactNode);
};

function MyPopup(props: MyPopupProps & Omit<PopupProps, "children">) {
  return <Popup {...(props as PopupProps)} />;
}

function App() {
  return (
    <>
      <div>
        <MyPopup trigger={<button>Information</button>} modal>
          {(close) => (
            <div className="modal">
              <div>
                Come on ladies
                <br />
                let's get in formation
              </div>
              <button
                onClick={() => {
                  close();
                }}
              >
                close
              </button>
            </div>
          )}
        </MyPopup>
      </div>
    </>
  );
}

export default App;


Relaterade artiklar