How to type narrow JSX.Element

I’d like to have a variable that can be either a React component or a string, like this:

function MyComponent(): JSX.Element {
  let icon: JSX.Element | string = "/example.png";  // (simplified)

  return <div>{typeof icon === "JSX.Element" ? icon : <img src={icon} />}</div>;
}

however TS complains about my condition saying:

TS2367: This condition will always return ‘false’ since the types ‘"string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"’ and ‘"JSX.Element"’ have no overlap.

What should I do?

>Solution :

The typeof operator cannot return "JSX.Element". It can only return the string types listed in that error message:

"string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"

Which means that you will need to check against something in that list, like "string".

function MyComponent(): JSX.Element {
  let icon: JSX.Element | string = "/example.png";
  
  return <div>{typeof icon === "string" ? <img src={icon} /> : icon }</div>;
}

Leave a Reply