mxmtsk
mxmtsk

Reputation: 4685

React children is a function: How to define TypeScript type correctly?

I have a small React Component where the child is a function. I can't seem to figure out how to define the children prop in TypeScript.

class ClickOutside extends React.PureComponent<Props, {}> {
  render() {
    const { children } = this.props;

    return children({ setElementRef: this.setElementRef });
  }
}

I'm calling it this way:

<ClickOutside onOutsideClick={() => this.setState({ isOpen: false })}>
  {({ setElementRef }) => (
    <div ref={setElementRef}>
      {trigger}
      {children}
    </div>
  )}
</ClickOutside>

And this is what I tried to define the prop but it does not work at all. I have tried several other things but failed and I'm kinda lost here.

type Props = {
  children: ({ setElementRef: (el: HTMLElement) => any }) => React.ReactNode,
  onOutsideClick: Function,
}

EDIT:

This produces ';' expected. on =>

When I change the type definition this way:

type Props = {
  children: ({ setElementRef: (el: HTMLElement) => any }),
  onOutsideClick: Function,
}

It produces this error:

Cannot invoke an expression whose type lacks a call signature. Type '{ setElementRef: (el: HTMLElement) => any; } | ({ setElementRef: (el: HTMLElement) => any; } & string) | ({ setElementRef: (el: HTMLElement) => any; } & number) | ({ setElementRef: (el: HTMLElement) => any; } & false) | ({ ...; } & true) | ({ ...; } & ReactElement<...>) | ({ ...; } & ReactNodeArray) | ({ ...; } & Re...' has no compatible call signatures.

Upvotes: 9

Views: 9308

Answers (1)

jaws
jaws

Reputation: 2022

You need to define the type of setElementRef in the de-structured object parameter of the children prop:

type Props = {
 children(options: { setElementRef(el: HTMLElement): any } ): React.ReactNode;
};

Remember that when de-structuring an object, the : symbol performs its JavaScript duties and reassigns a property name, whereas in this example you're expecting it to designate a type.

Upvotes: 6

Related Questions