I've read and tried suggestions found in Argument of type '(e: CustomEvent) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject' but haven't been able to sensibly apply them to my situation
I've taken over a project that was TS2.0 and I'm looking to move to 3.1 with it. I've read around regarding the error in the title and sort of understand why it occurs, but my typescript knowledge is limited at this point
I have these classes:
EventTargetImpl seems to be a class for managing a collection of event listeners
class EventTargetImpl implements EventTarget {
private eventListeners: any = {};
public addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void {
if (!this.eventListeners.hasOwnProperty(type))
this.eventListeners[type] = [];
this.eventListeners[type].push(listener);
}
public dispatchEvent(event: Event): boolean {
var type = event.type;
if (!this.eventListeners.hasOwnProperty(type)) {
this.eventListeners[type] = [];
}
for (var i = 0; i < this.eventListeners[type].length; i++) {
this.eventListeners[type][i].call(this, event);
}
return true;
}
public removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void {
if (!this.eventListeners.hasOwnProperty(type))
return;
var listenerIndex = this.eventListeners[type].indexOf(listener);
if (listenerIndex === -1)
return;
this.eventListeners[type].splice(listenerIndex, 1);
}
}
InputEvent class defines constant strings of event names that are some kind of local version of events.
class InputEvent extends EventImpl
{
public static TYPE_UP = "up";
constructor(type: string) {
super(type);
}
}
..but other than that doesn't seem to do much other than extend EventImpl:
class EventImpl implements Event
{
public bubbles: boolean;
public cancelBubble: boolean;
public cancelable: boolean;
public currentTarget: EventTarget;
public defaultPrevented: boolean;
public eventPhase: number;
public isTrusted: boolean;
public returnValue: boolean;
public srcElement: Element;
public target: EventTarget;
public timeStamp: number;
public type: string;
public initEvent(eventTypeArg: string, canBubbleArg: boolean, cancelableArg: boolean): void { throw "not implemented";}
public preventDefault(): void {
this.defaultPrevented = true;
}
public stopImmediatePropagation(): void { throw "not implemented"; }
public stopPropagation(): void { throw "not implemented";}
public AT_TARGET: number;
public BUBBLING_PHASE: number;
public CAPTURING_PHASE: number;
constructor(type: string) {
this.type = type;
}
}
InputWrapper. This class seems to have/hold an HTML element and either registers standard handlers for the element's events, or it replaces them with handlers attached to itself, of the local type events named in InputEvent
class InputWrapper extends EventTargetImpl {
constructor(private element: HTMLElement) {
super();
this.attachListeners();
}
private attachListeners(): void {
var detachGlobalListeners: () => void;
var attachGlobalListeners: () => void;
var mouseUpEventHandler = (event) => {
var point = this.normaliseMouseEventCoords(event);
this.handleMouseUp(point.x, point.y, event, InputType.Mouse);
detachGlobalListeners();
};
this.element.addEventListener("mouseup", (event) => {
if (!this.globalMode) {
this.handleMouseUp(event.offsetX, event.offsetY, event, InputType.Mouse);
}
});
detachGlobalListeners = () => {
this.globalMode = false;
window.removeEventListener("mouseup", mouseUpEventHandler);
};
attachGlobalListeners = () => {
this.globalMode = true;
window.addEventListener("mouseup", mouseUpEventHandler);
};
}
private handleMouseUp(x: number, y: number, event: Event, inputType: InputType): void {
event.stopPropagation();
event.preventDefault();
this.dispatchEvent(new InputEvent(InputEvent.TYPE_UP, { x: x, y: y }, inputType));
}
}
Here's where it's used and also where I get the error. I get a similar error on the dispatchEvent call in the lines of code just above too:
var inputWrapper = new InputWrapper(this.foreground);
inputWrapper.addEventListener(InputEvent.TYPE_UP, (event: InputEvent) => {
this.handleMouseUp(event.coords.x, event.coords.y);
});
I linked an SO answer I've already taken a look at; I like jcalz's suggestion that I can declaration-merge in my local events as being of type InputEvent and then use a strongly typed overload of addEventHandler, rather than a stringly typed one, but I can't work out where/how to do this in the object/inheritance hierarchy I have
I also tried FrederikKrautwald's suggestion of tacking as (e: Event) => void) onto the end of the inline function but TypeScript changes to complaining
Conversion of type '(event: InputEvent) => void' to type '(e: Event) => void' may be a mistake because neither type sufficiently overlaps with the other
A modified form of JacobEvelyn's suggestion is most like I'd do it in C#, if I had a specific type boxed in a generic one:
inputWrapper.addEventListener(InputEvent.TYPE_UP, (event: Event) => {
let iv: InputEvent = (event as InputEvent);
this.handleMouseUp(iv.coords.x, iv.coords.y);
});
But again I get the "neither type sufficiently overlaps with the other" error