Lots of runtime type errors when using React's event types
This is a:
- [ ] Bug Report
- [ ] Feature Request
- [x] Question
- [ ] Other
Which concerns:
- [x] flow-runtime
- [x] flow-runtime-cli
- [ ] babel-plugin-flow-runtime
- [ ] flow-runtime-validators
- [ ] flow-runtime-mobx
- [ ] flow-config-parser
- [ ] The documentation website
I have a couple questions on the correct way to use flow-runtime in a large project.
What is the current behaviour?
I have a react component with a field change handler like:
// app/MyComponent.js
class MyComponent extends Component<Props, State> {
...
handleFieldChange = (event: SyntheticInputEvent<HTMLInputElement>) => {
const { name, value } = event.target;
// onChange logic
}
handleOnSubmit = (event: SyntheticEvent<HTMLFormElement>) => {
// onSubmit logic
}
render() {
// render logic
}
}
I ran flow-runtime generate app/MyRuntime.js and have a couple separate issues here.
- The main issue is that when the onChange or onSubmit runs, I get a TON of errors output that certain parts of the object are missing, for example:
Uncaught TypeError: event.currentTarget.forceSpellcheck must be a function
Expected: () => void
Actual Value: undefined
Actual Type: void
(see this gist for the full list).
- The generated types definition file is HUGE... over 11,000 lines of code and adding about 5.5 minutes to the webpack bulid time
What is the expected behaviour?
- For the first issue, I guess that the types are incorrect (the properties that are erring should be optional but aren't), but no one has ever really noticed because a missing property wouldn't technically be an error in standard flow.
I'm assuming the solution for that is to find/create my own simplified version of the types that only have what I need. Does anyone know if such types exist already?
- I would have hoped that this wouldn't add too much overhead to our webpack build, maybe I should instruct babel to ignore files generated by flow-runtime-cli?
Which package versions are you using?
0.17
This is one example of why I prefer to use runtime type checks only in specific places in my app rather than turning them on across the board. I typically create and reify the types I want to check at runtime in a folder that specifically has babel-plugin-flow-runtime turned on. Then I import the reified type validators anywhere else and specifically call someType.assert(value).
The thought of checking the entire shape of every event (potentially more than once per event too) makes me nervous about performance; I certainly wouldn't want to try it in an app that has to respond to mouse drags at 30 fps. So I tend to think of blanket runtime assertions as more of a dev tool than something useful for production.
Another option is to replace SyntheticInputEvent<HTMLInputElement> with {target: {name: string, value: string}} (only the properties you actually need). It would avoid needless runtime checks anyway.
Solution that worked for me is to remove dom from the builtins, because then flow-runtime checks with instanceof:
rm node_modules/flow-runtime-cli/flow-builtins/dom.js ; flow-runtime generate ./src > ./src/typedefs.js
Maybe flow-runtime should not include builtins classes so that they can always be checked with instanceof or do you see any case where it should not ?