我已经阅读并尝试过在Argument of type '(e: CustomEvent) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject'中找到的建议,但未能将它们明智地应用到我的情况中。
我已经接手了一个名为TS2.0的项目,我希望用它来实现3.1。我已经阅读过关于标题中错误的内容,并对为什么会出现错误有一定的理解,但是我的打字本知识在这一点上是有限的。
我有这样的课程:
EventTargetImpl似乎是一个用于管理事件侦听器集合的类。
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 InputEvent extends EventImpl
{
public static TYPE_UP = "up";
constructor(type: string) {
super(type);
}
}除此之外,..but似乎除了扩展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。这个类似乎有/持有一个HTML元素,或者为元素的事件注册标准处理程序,或者用附加在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));
}
}这里是使用它的地方,也是我得到错误的地方。代码行中的dispatchEvent调用也有类似的错误,如下所示:
var inputWrapper = new InputWrapper(this.foreground);
inputWrapper.addEventListener(InputEvent.TYPE_UP, (event: InputEvent) => {
this.handleMouseUp(event.coords.x, event.coords.y);
});我链接了一个我已经看过的答案;我喜欢jcalz的建议:我可以声明--在本地事件中合并为InputEvent类型,然后使用强类型的addEventHandler重载,而不是输入的重载,但我无法确定在对象/继承层次结构中如何做到这一点。
我还尝试了FrederikKrautwald的建议,将as (e: Event) => void)添加到内联函数的末尾,但是TypeScript变成了抱怨
将类型“(Event: InputEvent) => void”转换为“(e: Event) => void”可能是一个错误,因为两种类型都没有与另一种类型充分重叠
JacobEvelyn的建议的一种修改形式就像我在C#中所做的那样,如果我在一个通用的建议中有一个特定类型的话:
inputWrapper.addEventListener(InputEvent.TYPE_UP, (event: Event) => {
let iv: InputEvent = (event as InputEvent);
this.handleMouseUp(iv.coords.x, iv.coords.y);
});但是,我再次得到了“类型与另一个类型都没有充分重叠”的错误。
发布于 2018-12-18 17:19:45
如何解决“两种类型与另一种类型都不充分重叠”错误
初步警告:一般来说,类型断言是不安全的。编译器通常不允许您做事情,因为这样做是错误的。然而,也有许多情况下,您确信某些东西是安全的,但编译器并不信服。您可以使用类型断言来强制编译器接受您的真实版本。这一切都很好,除非您碰巧错了,在这种情况下,您可能会出现疯狂的运行时行为,您不应该责怪试图警告您的糟糕的编译器。然而,编译器并不像人类那么聪明,所以断言通常是必要的。从现在开始,我假设您想要的断言是足够安全的。
下面是一个给出您遇到的错误的一般示例。
function assert<T, U>(t: T): U {
return t as U; // error
// [ts] Conversion of type 'T' to type 'U' may be a mistake because
// neither type sufficiently overlaps with the other. If this was
// intentional, convert the expression to 'unknown' first.
}我们试图断言T类型的值是U类型,并得到了“两种类型都没有充分重叠”的错误。基本上,类型断言可以用于将类型扩展到超级类型,这是安全的,因为您正在变得更一般(每只狗都可以正确地称为动物);它们也可以用于将类型缩小到更特定的类型,这是不安全的,因为您是更具体的(不是每种动物都可以正确地称为狗).这种类型安全性的缺乏是有意的,也是我们最初有断言的原因。但在TypeScript类型中,断言不能直接从一种类型转换为既不窄也不宽的不相关类型(因此我可以直接断言猫是动物,我可以直接断言动物是狗,但我不能直接断言猫是狗)。
解决这一问题的关键也在错误消息中提到:“首先将表达式转换为unknown”:
function assert<T, U>(t: T): U {
return t as unknown as U; // works
}错误已经消失,因为我们将t从T类型一直扩展到顶型 unknown,然后从unknown扩展到U类型。每个步骤都是允许的,但是不能跳过中间的步骤。(我不能说“这只猫是一只狗”,但我可以说“这只猫是一只狗的动物”)
您还可以使用其他可能的中间类型;它只需是两个无关类型的公共超级类型或公共子类型:
return t as unknown as U; // okay, widen T to top type unknown, and narrow unknown to U
return t as (T | U) as U; // okay, widen T to (T | U), and narrow (T | U) to U
return t as never as U; // okay, narrow T to bottom type never, and widen never to U
return t as (T & U) as U; // okay, narrow T to (T & U), and widen (T & U) to U
return t as any as U; // okay, any is both top-like and bottom-like,
// so you are, uh, "narrowidening" it through any 这种中间人断言是一种相当普遍的做法(特别是t as any as U,因为unknown在TypeScript 3.0中只是介绍 ),所以不要对使用它感到太难过。麻烦的本质主要是强迫您考虑您正在做的事情:您确定这个值可以作为这种类型来处理吗?如果不是,其他一些解决方案将比类型断言更好。如果是的话,那就继续!
希望这会有所帮助;祝你好运!
https://stackoverflow.com/questions/53833908
复制相似问题