I simply want to do this with my KeyboardEvent
var tag = evt.target.tagName.toLowerCase();
While Event.target is of type EventTarget it does not inherit from Element. So I have to cast it like this:
var tag = (<Element>evt.target).tagName.toLowerCase();
This is probably due to some browsers not following standards, right? What is the correct browser agnostic implementation in TypeScript?
PS: I am using jQuery to capture the KeyboardEvent.
This question is related to
typescript
Using typescript, I use a custom interface that only applies to my function. Example use case.
handleChange(event: { target: HTMLInputElement; }) {
this.setState({ value: event.target.value });
}
In this case, the handleChange will receive an object with target field that is of type HTMLInputElement.
Later in my code I can use
<input type='text' value={this.state.value} onChange={this.handleChange} />
A cleaner approach would be to put the interface to a separate file.
interface HandleNameChangeInterface {
target: HTMLInputElement;
}
then later use the following function definition:
handleChange(event: HandleNameChangeInterface) {
this.setState({ value: event.target.value });
}
In my usecase, it's expressly defined that the only caller to handleChange is an HTML element type of input text.
JLRishe's answer is correct, so I simply use this in my event handler:
if (event.target instanceof Element) { /*...*/ }
With typescript we can leverage type aliases, like so:
type KeyboardEvent = {
target: HTMLInputElement,
key: string,
};
const onKeyPress = (e: KeyboardEvent) => {
if ('Enter' === e.key) { // Enter keyboard was pressed!
submit(e.target.value);
e.target.value = '';
return;
}
// continue handle onKeyPress input events...
};
@Bangonkali provide the right answer, but this syntax seems more readable and just nicer to me:
eventChange($event: KeyboardEvent): void {
(<HTMLInputElement>$event.target).value;
}
I use this:
onClick({ target }: MouseEvent) => {
const targetDivElement: HTMLDivElement = target as HTMLDivElement;
const listFullHeight: number = targetDivElement.scrollHeight;
const listVisibleHeight: number = targetDivElement.offsetHeight;
const listTopScroll: number = targetDivElement.scrollTop;
}
Could you create your own generic interface that extends Event
. Something like this?
interface DOMEvent<T extends EventTarget> extends Event {
target: T
}
Then you can use it like:
handleChange(event: DOMEvent<HTMLInputElement>) {
this.setState({ value: event.target.value });
}
I'm usually facing this problem when dealing with events from an input
field, like key up. But remember that the event could stem from anywhere, e.g. from a keyup
listener on document
, where there is no associated value
. So in order to correctly provide the information I'd provide an additional type:
interface KeyboardEventOnInputField extends KeyboardEvent {
target: HTMLInputElement;
}
...
onKeyUp(e: KeyboardEventOnInputField) {
const inputValue = e.target.value;
...
}
If the input to the function has a type of Event
, you might need to tell typescript what it actually is:
onKeyUp(e: Event) {
const evt = e as KeyboardEventOnInputField;
const inputValue = evt.target.value;
this.inputValue.next(inputValue);
}
This is for example required in Angular.
For retrieving property you must cast target to appropriate data type:
e => console.log((e.target as Element).id)
Source: Stackoverflow.com