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?
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.