Reputation: 10603
I have this code:
<select class="form-control" on:change={pathChanged}>
The signature for pathChanged
is:
function pathChanged(event: { target: HTMLSelectElement }) {
When I run that through tsc
using npm run check
, I get this error:
Error: Type '(event: { target: HTMLSelectElement; }) => void' is not assignable to type 'FormEventHandler<HTMLSelectElement>'.
Types of parameters 'event' and 'event' are incompatible.
Type 'Event & { currentTarget: EventTarget & HTMLSelectElement; }' is not assignable to type '{ target: HTMLSelectElement; }'.
Types of property 'target' are incompatible.
Type 'EventTarget | null' is not assignable to type 'HTMLSelectElement'.
Type 'null' is not assignable to type 'HTMLSelectElement'. (ts)
<select class="form-control" on:change={pathChanged}>
What signature should pathChanged
have?
Upvotes: 9
Views: 9198
Reputation: 3629
A convenient option is to use ChangeEventHandler
:
const pathChanged: ChangeEventHandler<HTMLSelectElement> = (event) => {
console.log(event.currentTarget)
}
This will correctly type event
, event.target
and event.currentTarget
(use it in case the event bubbles up).
See the difference between target
and currentTarget
on MDN.
Upvotes: 1
Reputation: 184386
The event target
is less specific1 than you would want it to be. In this scenario I usually use a type assertion within the function to work around this.
function pathChanged(event: Event) {
const target = event.target as HTMLSelectElement;
// ...
}
Though the error states that currentTarget
should be typed correctly, so using that should work as well:
function pathChanged(event: { currentTarget: HTMLSelectElement })
If an event has a more specific type than just Event
, e.g. MouseEvent
, the types can be combined using &
:
function onMouseUp(event: MouseEvent & { currentTarget: HTMLSelectElement })
1 The reason for that is that most events bubble and the target
often can be any element within the element with the handler on it. currentTarget
always refers to the element with the handler and thus can be typed definitively.
Upvotes: 21
Reputation: 163
I did this in an input type file
:
// added this interface
interface FormEventHandler<T> {
target: EventTarget | null;
}
// then in the function
const onChangeFile = async (event: FormEventHandler<HTMLInputElement>) => {
const target = event.target as HTMLInputElement;
// your code
}
Upvotes: 2