1

I have a question about JavaScript's native addEventListener, normally we are using it like js selectElement.addEventListener('change', (event) => { const value = event.target.value });

but today I was looking at the type definition for it in TypeScript, it says the callback we pass into the addEventListener has this signature

(this: HTMLElement, ev: HTMLElementEventMap[K]) => any

so the first param it takes is actually an html element. I am a bit confused as we normally treat the first param as an event object as in my first example there.

Joji
  • 2,372
  • 1
  • 12
  • 31
  • "*the first param it takes is actually an html element*" no, it's a description of the `this` value, not a parameter it takes. – VLAZ Dec 19 '20 at 17:59

2 Answers2

2

so the first param it takes is actually an html element.

No. It says that the this value is an HTML element.

function handler(event) {
    console.log("this", this instanceof HTMLElement);
    console.log("event", event instanceof Event);
}

document.querySelector("button").addEventListener("click", handler);
<button>Content</button>

Note that arrow functions use a lexical this instead of a contextual one so that won't work if you use an arrow function like your first example.

Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
  • thanks... so does the `this` get implicitly passed to the function? this is just the why how TS annotates `this` value's type `(this: HTMLElement, ev: HTMLElementEventMap[K]) => any`? – Joji Dec 19 '20 at 18:21
1

Here is small example:

class B {
  handleB() { }
}
class A {
  // I have defined [B] as a this/context of callback
  add(callback: (this: B, ev: number) => void) { }
}

const result = new A();

result.add(function (el) { // el -> number
  const x = this.handleB // TS thinks that [this] of this function is [B]. 

})

More information about typing this You can find here

captain-yossarian
  • 6,577
  • 1
  • 8
  • 21
  • thanks for the explanation. it is kinda interesting that in plain javascript if I write this ` async function handleChange(this) {}` I would get an error for `Unexpected keyword 'this'` but in TypeScript that would be acceptable... Do you know what caused the difference here? – Joji Dec 20 '20 at 01:12
  • Because when you wtite THIS in TS, it is like defining a context of callback. You should not treat it as an argument. It is similar how you define SELF in python or rust – captain-yossarian Dec 20 '20 at 09:38