Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Text in JSX has the type 'string', but the expected type of 'children' is 'string | Element | Element[]

I have a custom React button component that I want to be able to take optional strings with or without optional icons (JSX.Element) as cildren.

My interface looks like this

interface IUploadFileButtonProps {
  children: string | JSX.Element | JSX.Element[];
}

And the implementation:

// Does not work
<UploadFileButton>
  <FaUpload />
  Add new list
</UploadFileButton>

// Works
<UploadFileButton>
  No icon, just text
</UploadFileButton>

// Works
<UploadFileButton>
  <FaUpload />
</UploadFileButton>

// Works
<UploadFileButton>
  <FaUpload />
  <FaUpload />
</UploadFileButton>

I get this error message:

Text in JSX has the type 'string', but the expected type of 'children' is 'string | Element | Element[]

Which I suppose is because Typescript expects one of the types, but not more than one type at the time.

How can I specify an optional string and/or optional JSX.Elements as a type (if that makes any sense)?

I could bail out and go with any, but I want to know the correct typing for this scenario.

like image 604
mottosson Avatar asked Mar 09 '20 16:03

mottosson


2 Answers

You can use React.ReactNode for typing the children array, why are you defining your own?

interface IUploadFileButtonProps {
  children: React.ReactNode;
}
like image 67
tudor.gergely Avatar answered Sep 18 '22 23:09

tudor.gergely


You can add (string | JSX.Element)[] to your type definition.

interface IUploadFileButtonProps {
  children: string | JSX.Element | JSX.Element[] | (string | JSX.Element)[];
}
like image 26
giotskhada Avatar answered Sep 17 '22 23:09

giotskhada