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

Viewed 2076

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.

2 Answers

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

interface IUploadFileButtonProps {
  children: React.ReactNode;
}

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

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