Difference between TypeScript optional fields and propTypes isRequired
mz8i opened this issue · comments
Consider the following component:
const Foo: React.FC<{bar: boolean}> = (props) => (
props.bar != undefined ? <h1>Full!</h1> : <h2>Empty.</h2>
);
and its usage in another component's render function:
render() {
const barProp = null;
return <Foo bar={barProp} />;
}
Now the problem is with the handling of null/undefined values by TypeScript and propTypes. There is a discrepancy - in TS, the above won't throw an error, because the value for bar
is supplied (even though it's null
). But babel-plugin-typescript-to-proptypes
will generate propTypes with isRequired
here (as bar
is not marked as optional), and React shows a warning that bar
is required but it's null
.
I don't feel marking the field in the interface as bar?: boolean
is a good approach to solve such an issue, because then <Foo />
would be a valid use of the component, but that can lead to hard-to-spot bugs where a (potentially null-valued) property wasn't passed down the component tree.
On the other hand, having warnings pop up everywhere because of this issue is not great either. Out of a lack of a better idea, I'd suggest having a configuration switch to indicate whether isRequired
should be generated at all - this would work if someone wants to just check the types of props at runtime, but not enforce their presence.
Yeah, it's one of those weird scenarios where null
is valid value and there's not enough type information. I'm not sure of a solution either besides another option to control this.
Having an option like generateIsRequired
would be great - in our project before moving to TypeScript, we only used isRequired
in very rare cases anyway, and for quite a few props null is a valid value, so skipping that aspect of generation altogether would make most sense, but currently it's not configurable.
Added a strict
option. Will be in next release.