Home > Software engineering >  How to please TS compiler using conditional React JSX components
How to please TS compiler using conditional React JSX components

Time:03-08

I saw this pattern of using React component to make conditionals and ternaries inlined in JSX a bit more readable. But, would love to hear if someone has any input to a TS related "problem" with using such an approach.

So, given I have my component <MyComponent /> it's defined so that it takes a prop foo. This prop must be a string.

type Props = { foo: string};

const MyComponent: FC<Props> = ({ foo }) => ...

Then, I have a wrapper component to help me make som conditional statements a little easier to reason about (sometimes);

type Props = { condition: boolean};
const Conditional: FC<Props> = ({ condition, children }) => (condition ? <>{children}</> : null);

Now, example A works (ofc...) - but example B does not. Maybe someone knows exactly why, I might have some guesses but not that comfortable around React yet to out them ;) And of course even more interesting, maybe someone has an idea how to make example B work?

Example A;
{bar && <MyComponent foo={bar} />}

Example B;
<Conditional condition={bar!==undefined}>
  <MyComponent foo={bar} />
</Conditional>

B gives the error; Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.ts(2322)

CodePudding user response:

In a simple way, you can tell your typescript compiler that the bar value is non-nullable by using ! like this

// Example B;
<Conditional condition={bar!==undefined}>
  <MyComponent foo={bar!} /> // notice the exclamation mark here
</Conditional>

CodePudding user response:

TypeScript just seems to be unaware that you are already guaranteeing that the bar variable is undefined through the use of your Conditional component.

There's a few ways to get around this: You can use the Non-null assertion operator

<Conditional 
  condition={bar /* You can simplify this and do a truthy check*/}
>
  <MyComponent foo={bar! /* Note the exclamation mark */} />
</Conditional>

You can also try type assertion where you tell typescript that a variable is of a certain type.

<Conditional 
  condition={bar}
>
  <MyComponent foo={bar as string} />
</Conditional>
  • Related