sev
sev

Reputation: 1822

Typescript react children with type specified in function directly instead of using an interface

Why does this work:

interface UserSidebarProps {
  children? : React.ReactNode
}

function UserSidebar({children}: UserSidebarProps) {
  return (
    <div>
      {children}
    </div>
  )
}

But this does not

function UserSidebar(children?: React.ReactNode) {
  return (
    <div>
      {children}
    </div>
  )
}
// Usage
<UserSidebar>hello world</UserSidebar>

When trying to use it, the second option gives an error in vscode of:

Type '{ children: Element | null; }' is not assignable to type 'IntrinsicAttributes & ReactNode'.
  Type '{ children: Element | null; }' is missing the following properties from type 'ReactPortal': key, type, props

I would have thought these two definitions are completely equivalent, how are they different and what am I doing wrong?

Upvotes: 0

Views: 2105

Answers (2)

Codebling
Codebling

Reputation: 11382

The problem is not using an interface or not, the problem is that you changed the signature of the function (the arguments it accepts). If I remove the Typescript, can you see the difference?

function UserSidebar({children}) {

function UserSidebar(children) {

React passes props to components, and you have said that your component DOES NOT accept props, only a ReactNode.

Try adding the brace brackets again.

function UserSidebar({children}: {children: React.ReactNode;}) {

Upvotes: 1

Pedro Vitorino
Pedro Vitorino

Reputation: 46

What happens is that when creating a component, the props definition (the parameter of your function) should be of a class where its properties represents the props of your component. Practically, this means that on the second example you should do something like:

function UserSidebar({children}: {children?: React.ReactNode}) {
  return (
    <div>
      {children}
    </div>
   )
}

Or you could use the PropsWithChildren class like this:

function UserSidebar({children}: PropsWithChildren) {
  return (
    <div>
      {children}
    </div>
   )
}

Upvotes: 1

Related Questions