0

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)

  • In the context of `MyComponent`, the compiler cannot be certain that `bar` is not `undefined`. Also not sure you want to return `null` if `condition` is a false value. – crashmstr Mar 07 '22 at 19:53

2 Answers2

0

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>
Ahmed Tarek
  • 318
  • 3
  • 9
0

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>
Abir Taheer
  • 2,502
  • 3
  • 12
  • 34