41

What is the correct type for 'e' as in uploadImage function parameter?

public uploadImage(e /* :type of e */){
 const image = e.target.files[0];
 const reader = new FileReader();
 reader.readAsDataURL(image);
 reader.onload = e =>{
    this.previewImage = e.target.result;
    console.log(this.previewImage);
 };
}

In template I have this

<input type="file" accept="image/jpeg" @change=uploadImage>

6 Answers 6

31

The type is just Event. Relevant information is on e.target property.

Sign up to request clarification or add additional context in comments.

Comments

19

Obviously I'm late to the party, but I was rewriting some legacy components. In the end I ran into Typescript errors - the template event didn't like me destructuring directly because the target was EventTarget, not HTMLInputElement or whatever the given element I needed.

So instead of directly destructuring the arguments I just set it afterwards as a variable, using the as keyword.

Example:

foo(event: Event) {
  const el = event.target as HTMLInputElement
  // do stuff
}

I wish I knew some handy trick to destructure it from the arguments directly with the correct type, but alas I haven't been that fortunate.

Comments

16

You can use your self annotation for this type.

interface InputFileEvent extends Event {
    target: HTMLInputElement;
}

public uploadImage(e: InputFileEvent) {
    const image = e.target.files[0];
    const reader = new FileReader();
    reader.readAsDataURL(image);
    reader.onload = e =>{
        this.previewImage = e.target.result;
        console.log(this.previewImage);
   };
}

1 Comment

TS is still complaining about incompatible vue @events
3

The Vue documentation has this section: Typing Event Handlers.

Their recommendation is (not too satisfying) to use the generic Event type, and type assert properties as needed:

handleChange( event: Event ){
  console.log( (event.target as HTMLInputElement).value );
}

I don't see a really better solution for now.

Future ?

The HTMLElement change event (which you are using on the HTMLInputElement in your example) is indeed just a generic Event.

In other cases it would be desirable to use a more specific event, e.g. the click event is of the type PointerEvent, but it seems that only Event is defined right now for all events, so we have to deal with it.

Also specifying the target elements type would be nice (with "Generics"), like:

function handler( event: PointerEvent<HTMLInputElement> ){} // <-- doesn't work yet

But the specific elements type seems not to be available at this point. Maybe this will be supported in some future version of Vue (?).

Notes about not working solutions

One may try to define own types (I tried that myself), like:

interface MyPointerEvent<T extends EventTarget> {
    target: T;
}

const handleClick = function(event: MyPointerEvent<HTMLTableCellElement>){
 // ...
};

This gives you auto completion and correct typing inside the function, but this would still cause an error in Vue templates:

<template>
    <button @click=handleClick></button>
//   ^-- Error: `onClick: ( event: MyPointerEvent<HTMLTableCellElement> ) => void;`
//       is not assignable to `ButtonHTMLAttributes & ReservedProps & Record<string, unknown>`
</template>

Comments

2

If you give the type as Event, then you will be unable to do e.target.files[0]; as TS will complain that Property 'files' does not exist on type 'target' error in typescript. The simplest solution is to give it type as any referring shusson's solution here: Property 'files' does not exist on type 'EventTarget' error in typescript but even this didn't work for me so I ended up just not using TS for that particular Vue component

1 Comment

If the type any does not even work, you probably tried to make something work that can't work, may it be with or without types. Using any is wrong in the first place because by that you disable the advantage of Typescript. If you plan to do that, the better solution is (honestly) to uninstall Typescript.
2

There are different type of events and types. For example you can use DragEvent type for drag action : https://developer.mozilla.org/en-US/docs/Web/API/DragEvent.
There is also InputEvent for inputs. : https://developer.mozilla.org/en-US/docs/Web/API/InputEvent.
The Event is more generic. enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.