简体   繁体   中英

How to declare type for functional React component using object destructuring in props?

I am still learning TypeScript and declaring (advanced) types. I am trying to convert my CRA project to typescript and I have following component in it. How I should declare the types for this?

This component is almost 1:1 from react-router-dom examples, but I couldn't find any example showing this written in TypeScript

// ProtectedContent.tsx

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import Auth from '../services/Auth';

const ProtectedContent = ({ component: Component, ...rest }) => {
  return (
    <Route {...rest} render={(props) => {
      if (Auth.isAuthenticated()) {
        return (
          <Component {...props} />
        );
      } else {
        return (
          <Redirect to={{
            pathname: '/auth/signin',
            state: { from: props.location },
          }} />
        );
      }
    }} />
  );
};

export default ProtectedContent;

I tried creating an interface for the parameters:

interface PCProps extends HTMLAttributes<HTMLElement>{
  component: React.Component;
}

const ProtectedContent = ({ component: Component, ...rest }: PCProps) => {
   // .......
}

But then I was having problem with the line

return (
  <Component {...props} />
);

as there was error saying

JSX element type 'Component' does not have any construct or call signatures. ts(2604)

Then when I was trying to fix that I ended going down an insane rabbit hole and lost track and understanding of what was going on anymore.

So how should I declare the types for this so that the component could be any React component and then destructure rest of the props neatly?

TS version is 3.8.3


Edit: (Possible solution)

From the depths of internet I found this "solution". I can declare the component in the PCProps interface as 'ReactType' and the use it like this:

interface PCProps {
  component: React.ReactType;
}

const ProtectedContent = ({ component: Component, ...rest }): PCProps => {
  ...
}

This will get rid of the error, but why? What is this 'ReactType'? I went through the docs and found nothing related to it. Is there anyone experienced in React and TS who could explain this and also how this kind of component should be typed?

I don't really like to use this solution, because I have no idea what's happening.

Solution source


Edit2:

Sandbox showing original, proposed solution using React.FC and possible solution using React.ReactType. Check all the three files in this sandbox.

Sandbox for this question

Make sure your file extension is .tsx and not .ts and that you're declaring component: React.FC; . Working example: codesandbox.io/s/silly-hamilton-1xuyu?file=/src/App.tsx:95-97

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM