This works:
// @flow
import React, {Component} from 'react';
type Props = {};
class Delete extends Component<Props> {
targetElement: null | winndow.HTMLInputElement;
constructor(props: Props) {
super(props);
this.targetElement = null; // initialize to null
}
handleClick = (e: SyntheticEvent<> & {target: window.HTMLInputElement}) => {
this.targetElement = (e.target: window.HTMLInputElement).value;
};
render() {
return (
<input onClick={this.handleClick} value="hello" />
);
}
}
export default Delete;
but this doesn't:
...
handleClick = (e: SyntheticEvent<> & {target: window.HTMLInputElement}) => {
this.targetElement = e.target.value;
};
...
The error message is: Cannot get e.target.value because property value is missing in EventTarget.
1) I've already typed the "target" property to be window.HTMLInputElement, which has a value property, so why does Flow insist that property value is missing in EventTarget (why EventTarget?)
In the first place, before I added Flow annotations, the code works great, and there were no console errors about missing properties.
I'm really confused as to how this works - I've read this and this, and it seems there are a huge range of workarounds/solutions, but I'm not sure why they work. Also, those are 2-3 years old, and I'm not sure if they're still relevant now. I'm new to Flow, but really interested to master it!
I've already typed the "target" property to be window.HTMLInputElement, which has a value property
Not sure what you mean here, but for what it's worth, this is a working version of your example
// @flow
import React, { Component } from 'react'
type Props = {}
class Delete extends Component<Props> {
targetElement: ?HTMLInputElement
constructor(props: Props) {
super(props)
this.targetElement = null // initialize to null
}
handleClick = (e: SyntheticEvent<HTMLInputElement>) => {
this.targetElement = e.currentTarget
}
render() {
return <input onClick={this.handleClick} value="hello" />
}
}
export default Delete
Not sure what you mean here, but for what it's worth, this is a working version of your example
I meant I've already specified the "target" property to be of type window.HTMLInputElement:
...
class Delete extends Component<Props> {
> targetElement: null | winndow.HTMLInputElement;
constructor(props: Props) {
...
Also, is there a difference between HTMLInputElement and Window.HTMLInputElement? I found when experimenting that sometimes interchanging the two breaks the test, but I haven't been able to find a consistent theory/answer for it.
Update: I notice that if I change e.currentTarget to e.target I get an error Cannot assign e.target to this.targetElement because EventTarget [1] is incompatible with HTMLInputElement [2].. Is this supposed to happen? What if I require the "target" property instead of "currentTarget"?
Window.HTMLInputElement is not a valid type. If flow doesn't error for you when you use it, you might have an issue in your IDE
HTMLInputElement is a built in type
FYI - I like consulting this cheat-sheet whenever I forget what an internal type is called or for quickly finding their source
Update: I notice that if I change e.currentTarget to e.target I get an error Cannot assign e.target to this.targetElement because EventTarget [1] is incompatible with HTMLInputElement [2].. Is this supposed to happen? What if I require the "target" property instead of "currentTarget"?
There's actually an explanation for that in the source code, which links you here
Window.HTMLInputElementis not a valid type. If flow doesn't error for you when you use it, you might have an issue in your IDE
Flow doesn't error when I use it - I got the idea to try that from an answer to a previous issue. Is it supposed to produce an error? Because it was reported as a solution in that thread.
There's actually an explanation for that in the source code, which links you here
Thank you, I'll have a look!
It is def supposed to raise an error.
const element: ?window.HTMLInputElement = null
Put that on try flow and you'll see
3: const element: ?window.HTMLInputElement = null
^ Cannot resolve namewindow.
In that case, I believe this is caused by the create-react-app package. I created a new test project, and installed nothing but flow, and pasted the exact line const element: ?window.HTMLInputElement = null, and flow runs without any errors.
I'm happy to create a demonstration repo!
Most helpful comment
Not sure what you mean here, but for what it's worth, this is a working version of your example