I have a React component that, based on which prop it receives, might return either a non-clickable div
(ie, without an onClick
-prop) or a clickable button
(ie, with an onClick
-prop). How do I specify this in the Flow type annotation?
I used to use ?React$Element<*>
as the return type, but that didn't work, so I simply tried replacing *
with an object, specifying the types. ?React$Element<{ className: string }>
worked just fine, but I can't seem to add an optional onClick
. I've tried both onClick?: Function
- a syntax I've seen in some places - and onClick: ?Function
- as you see below - but both throw the error at the bottom.
type RequestDataButtonType = (props: Props) => ?React$Element<{
className: string,
onClick: ?Function,
}>
const RequestDataButton
: RequestDataButtonType
= ({ requestData, status }) => {
if (status === Status.REQUESTED) {
return (
<div className={css.requested}>
Contact details requested
</div>
)
} else if (status === Status.ERROR) {
return (
<button
className={css.error}
onClick={requestData}>
Error
</button>
)
} else if (status === Status.REQUESTING) {
return (
<div className={css.requesting}>
Requesting contact details
<LoadIndicator className={css.loadIndicator} />
</div>
)
} else {
return (
<button
className={css.request}
onClick={requestData}>
Request contact details
</button>
)
}
}
Flow throws the following errors for the above code (ignore line numbers, I've removed some irrelevant code):
> flow; test $? -eq 0 -o $? -eq 2
src/content/components/RequestDataButton/RequestDataButton.js:43
43: <div className={css.requested}>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ React element: `div`
33: type RequestDataButtonType = (props: Props) => ?React$Element<{
^ property `onClick`. Property not found in
43: <div className={css.requested}>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ props of JSX Intrinsic: `div`
src/content/components/RequestDataButton/RequestDataButton.js:57
57: <div className={css.requesting}>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ React element: `div`
33: type RequestDataButtonType = (props: Props) => ?React$Element<{
^ property `onClick`. Property not found in
57: <div className={css.requesting}>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ props of JSX Intrinsic: `div`
Found 2 errors
You can use $Shape<T>
to pass the typecheck.
This works:
type RequestDataButtonType = (props: Props) => ?React$Element<$Shape<{
className: string,
onClick: ?Function,
}>>
$Shape<T>
doesn't require all properties to be defined, but the ones that are defined must match the type definition.
In other words, you're describing any ReactElement
that can optionally have onClick
, but - if it does - then it must be a ?Function
.
Here's a fully working example (I replaced some of your types but the gist is there):
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.