<p dir="auto">Been having an issue with this snippet of code:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var reader = new FileReader();
var debug = {hello: &quot;world&quot;};
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});

reader.onload = function(evt){
  console.log(evt.target.result);
}
reader.readAsText(blob);"><pre class="notranslate"><code class="notranslate">var reader = new FileReader();
var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});

reader.onload = function(evt){
  console.log(evt.target.result);
}
reader.readAsText(blob);
</code></pre></div>
<p dir="auto">So when running this as plain JS, I end up logging <code class="notranslate">{hello:"world"}</code>. But this doesn't typecheck right now.</p>
<p dir="auto">So currently the interface structures involved in <code class="notranslate">lib.d.ts</code> are something like (trimmed for space):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="interface Event {
    target:EventTarget;
}

interface FileReader  extends EventTarget{
    onload:(ev:Event)=&gt;any;
    result: any;
}"><pre class="notranslate"><code class="notranslate">interface Event {
    target:EventTarget;
}

interface FileReader  extends EventTarget{
    onload:(ev:Event)=&gt;any;
    result: any;
}
</code></pre></div>
<p dir="auto">The interface signature makes it clear that <code class="notranslate">FileReader</code> is meant to be the target, but because of how the interfaces are structured, this doesn't bubble down properly.</p>
<p dir="auto">In a vacuum, the simple solution seems to be to make <code class="notranslate">Event</code> be generic on its target:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="interface Event&lt;T extends EventTarget&gt;{
    target:T
}

interface FileReader extends EventTarget{
    onload:(ev:Event&lt;FileReader&gt;)=&gt;any;
    result: any;
}"><pre class="notranslate"><code class="notranslate">interface Event&lt;T extends EventTarget&gt;{
    target:T
}

interface FileReader extends EventTarget{
    onload:(ev:Event&lt;FileReader&gt;)=&gt;any;
    result: any;
}
</code></pre></div>
<p dir="auto">But two things cause me to hesitate at this patch:</p>
<ul dir="auto">
<li>The <code class="notranslate">Event</code> interface is defined in the W3C DOM <a href="https://dom.spec.whatwg.org/#interface-event" rel="nofollow">spec</a> .I'm not quite sure what the policy is upstream with Edge on this, but introducing generics into the typing might be too much deviation from this.</li>
<li><code class="notranslate">Event</code> touches a lot of stuff, so there's a lot of collateral damage. I think it would require rewriting almost everything related to Events (kind of defeating the purpose of generating <code class="notranslate">lib.d.ts</code> from Edge).</li>
</ul>
<p dir="auto">As a side note, I've noticed that there's a lot of <code class="notranslate">onX(ev:Event&lt;Self&gt;)=&gt;any</code>-type event listeners a bit all over the place (where <code class="notranslate">Self</code> is the containing interface). I run into this quite a bit in my own code, I wonder if there's value in having a special type variable to refer to the containing class.</p>
<p dir="auto">Anyways, I wanted to get some feedback on this before moving forward.</p>
<p dir="auto">When using the Event interface from lib.d.ts, and attaching a listener, the callback will get an object of type Event. However, the Event's currentTarget property is of type EventTarget (whereas it's should be of type Element/HTMLElement).</p>