Search code examples
reactjstypescriptreact-typescript

How to type new props in React.cloneElement?


I like to pass down a state update function to all children elements like that:

React.Children.toArray(children)
.map(child => React.isValidElement(child) ?
React.cloneElement(child, {setNewItemPopup : setNewItemPopup}) : child)

TS tells me:

No overload matches this call.
  The last overload gave the following error.
    Argument of type '{ setNewItemPopup: React.Dispatch<React.SetStateAction<NewItemPopupProps | null>>; }' is not assignable to parameter of type 'Partial<unknown> & Attributes'.
      Object literal may only specify known properties, and 'setNewItemPopup' does not exist in type 'Partial<unknown> & Attributes'.ts(2769)

I don't know how to do the typing in this case. Can someone help me?


Solution

  • Since isValidElement takes a generic P which is a props and returns a valid ReactElement<P> so as long as you set the props for it which is the props of element you clone, then it should work.

    In short, set as following:

    // Just replace `any` with your actual type
    // while `{ setNewItemPopup: any }` is the props of `child`
    React.isValidElement<{ setNewItemPopup: any }>(child);
    
    // so full code looks like this:
    React.Children.toArray(children).map((child) =>
        React.isValidElement<{ setNewItemPopup: any }>(child) ? React.cloneElement(child, { setNewItemPopup: setNewItemPopup }) : child
      );