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>