title: Does the JavaScript event system violates the LSP?
body: <p><strong>I'm asking this more out of curiosity rather than really being concerned with it</strong>, but I've been wondering whether or not the JavaScript event system violates the <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle" rel="nofollow noreferrer">Liskov substitution principle (LSP)</a> or not.</p>
  
  <p>By calling <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget" rel="nofollow noreferrer"><code>EventTarget.dispatchEvent</code></a>, we may dispatch an <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event" rel="nofollow noreferrer"><code>Event</code></a> of an arbitrary type that might get handled by a registered <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventListener" rel="nofollow noreferrer"><code>EventListener</code></a>.</p>
  
  <pre><code>interface EventListener {
    void handleEvent(in Event evt);
  }
  </code></pre>
  
  <p>If I understand the LSP correctly, it would mean that <code>anyEventListener.handleEvent(anyEvent)</code> shouldn't fail. However, that is usually not the case since event listeners will often use properties of specialized <code>Event</code> sub-types.</p>
  
  <p>In a typed language that does not support generics, that design would basically require downcasting the <code>Event</code> object to the expected sub-type in the <code>EventListener</code>.</p>
  
  <p>From my understanding, the above design as is could be considered a violation of the LSP. Am I correct or the simple fact of having to provide a <code>type</code> when registering a listener through <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener" rel="nofollow noreferrer"><code>EventTarget.addEventListener</code></a> prevents the LSP violation? </p>
  
  <p><strong>EDIT:</strong> </p>
  
  <p>While everyone seems to be focusing on the fact that <code>Event</code> subclasses aren't violating the LSP, I was actually concerned about the fact that <code>EventListener</code> implementors would violate the LSP by strenthening the pre-conditions of the <code>EventListener</code>'s interface. Nothing in the <code>void handleEvent(in Event evt)</code> contract tells you that something may break by passing the wrong <code>Event</code> sub-type.</p>
  
  <p>In a strongly-typed language with generics that interface could be expressed as <code>EventListener&lt;T extends Event&gt;</code> so that the implementor can make the contract explicit e.g. <code>SomeHandler implements EventListener&lt;SomeEvent&gt;</code>.</p>
  
  <p>In JS there are obviously no actual interfaces, but event handlers still need to conform to the specification and there is nothing in that specification that allows a handler to tell whether or not it can handle a specific type of event.</p>
  
  <p>It's not really an issue because listeners aren't expected to be invoked on their own, but rather invoked by the <code>EventTarget</code> on which it was registered and <strong>associated with a specific type</strong>.</p>
  
  <p><strong>I'm just interested about whether or not LSP is violated according to the theory.</strong> I wonder if to avoid the violation (if theorically considered as such) the contract would have needed to be something like the following (even though it may have done more bad than good in terms of pragmatism):</p>
  
  <pre><code>interface EventListener {
    bool handleEvent(in Event evt); //returns wheter or not the event could be handled
  }
  </code></pre>