Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using dot notation with functional component in TypeScript

Official ReactJs documentation recommends to create components following the dot notation like the React-bootstrap library:

<Card>
  <Card.Body>
    <Card.Title>Card Title</Card.Title>
    <Card.Text>
      Some quick example text to build on the card title and make up the bulk of
      the card's content.
    </Card.Text>
  </Card.Body>
</Card>

Thanks to this question, I know that I can create this structure using functional components just like that in javascript:

const Card = ({ children }) => <>{children}</>
const Body = () => <>Body</>

Card.Body = Body

export default Card

Using TypeScript I decided to add the corresponding types to it:

const Card: React.FunctionComponent = ({ children }): JSX.Element => <>{children}</>
const Body: React.FunctionComponent = (): JSX.Element => <>Body</>

Card.Body = Body  // <- Error: Property 'Body' does not exist on type 'FunctionComponent<{}>'

export default Card

Problem is now that TypeScript don't allow the assignment Card.Body = Body and give me the error:

Property 'Body' does not exist on type 'FunctionComponent<{}>'

So how can I type this correctly in order to use this code structure?

like image 492
johannchopin Avatar asked Mar 27 '20 09:03

johannchopin


People also ask

Can we use functional component in typescript?

There are many we can create Functional Components in typescript. In Typescript React Component, Function takes props object and returns JSX data. Declare Normal Function with props parameters of the type above MessageProps (use type or interface).

What is a dot notation in typescript?

The question mark dot (?.) syntax is called optional chaining in TypeScript and is like using dot notation to access a nested property of an object, but instead of causing an error if the reference is nullish, it short-circuits returning undefined .

Can we use props in functional component?

Of course, you can still pass props from parent to child with functional components but the big difference is that you'll need to declare them in your functional component callback just as you would with any other type of function. Now you can access those props.


1 Answers

const Card: React.FunctionComponent & { Body: React.FunctionComponent } = ({ children }): JSX.Element => <>{children}</>
const Body: React.FunctionComponent = (): JSX.Element => <>Body</>

Card.Body = Body;

Or more readable:

type BodyComponent = React.FunctionComponent;
type CardComponent = React.FunctionComponent & { Body: BodyComponent };

const Card: CardComponent = ({ children }): JSX.Element => <>{children}</>;
const Body: BodyComponent = (): JSX.Element => <>Body</>;

Card.Body = Body;
like image 181
Roberto Zvjerković Avatar answered Oct 19 '22 00:10

Roberto Zvjerković