Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TS2322 - false | Element is not assignable to type ReactElement. Error does not consistently appear in app?

I understand what the error is saying and I have been able to fix it, but I was hoping someone could provide some clarification on why it's happening now and why it isn't happening in other areas of my app, as well as why a function and a ternary with essentially the same type signature produce different results.

I wanted to display a basic error message in the following style:

{!!error.message && (
  <Text>{error.message}</Text>
)}

But it gives the error mentioned in the title. I know false is handled by React and won't render anything, but knowing null is the preferred way of telling React not to render something I converted the above into a component. This makes the error go away:

const Error = () => {
  if (!error.message) return null;
  return <Text>{error.message}</Text>;
}

Out of curiosity, I tried the same thing with a ternary which should have the same signature:

{error.message ? <Text>{error.message}</Text> : null}

However this produces a very similar error to the one in the title, except it complain about null instead.

Knowing all 3 bits of code are valid React, and 2/3 being virtually identical, why is only one accepted by the TS compiler?

To further confuse things, I have the below in another part of my app and TS has no issue with it:

{!loaded && (
  <RootStack.Screen name={SCREENS.SPLASH} component={Splash} />
)}
{loaded && !userAuth.authenticated && (
  <>
    <RootStack.Screen name={SCREENS.SIGN_UP} component={SignUp} />
    <RootStack.Screen name={SCREENS.SIGN_IN} component={SignIn} />
  </>
)}
{loaded && userAuth.authenticated && (
  <RootStack.Screen name={SCREENS.TABS} component={Tabs} />
)}
like image 291
JmJ Avatar asked Dec 11 '25 22:12

JmJ


1 Answers

I also received this error using code similar to yours and similar to your observations, them being that the error can be avoided with React Fragments and occurs when you use conditional logic with a JSX.Element.

I dug into the React documentation regarding the conditional logic:

Inline If with Logical && Operator

You may embed expressions in JSX by wrapping them in curly braces. This includes the JavaScript logical && operator. It can be handy for conditionally including an element...

It works because in JavaScript, true && expression always evaluates to expression, and false && expression always evaluates to false.

Therefore, if the condition is true, the element right after && will appear in the output. If it is false, React will ignore and skip it.

Which means that the following code is attempting to evaluate the <text> element with type JSX.Element as a boolean, so type error.

{!!error.message && (
  <Text>{error.message}</Text>
)}

In terms of a solution to proceed with Inline && Operators conditionals, the easiest appears to be wrapping your logic in a React fragment like so:

<>                {/*<-------- wrap in fragment */}
{!!error.message && (
  <Text>{error.message}</Text>
)}
</>               {/*<-------- close the fragment */}

Related Questions

  • Error with && logical operator jsx and typescript
  • How to use ternary operator within the jsx of a react component along with typescript?
  • Why is ternary operator in jsx not working
like image 54
Harley Lang Avatar answered Dec 15 '25 19:12

Harley Lang



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!