由于 'No overload matches this call',无法将 eventName 和回调传递给 addEventListener

Can not pass eventName and callback to addEventListener because of 'No overload matches this call'

我试图在这个 class 的方法中将事件监听器添加到存储在 class 中的输入元素,它采用包含 eventName[= 的道具对象52=] 和 callback.

public setTextFieldInputListener({ eventName, callback }: TextFieldListenerProps): void {
    this.input.addEventListener(eventName, callback);
}

这个listener props对象是两个接口的联合类型BlurTextFieldCallbackPropsInputTextFieldCallbackProps

export type TextFieldListenerProps = BlurTextFieldListenerProps | InputTextFieldListenerProps;

export interface BaseTextFieldListenerProps {
    eventName: Extract<keyof GlobalEventHandlersEventMap, 'blur' | 'input'>;
    callback(e?: FocusEvent | Event): void;
}

export interface BlurTextFieldListenerProps extends BaseTextFieldListenerProps {
    eventName: Extract<keyof GlobalEventHandlersEventMap, 'blur'>;
    callback(e?: FocusEvent): void;
}

export interface InputTextFieldListenerProps extends BaseTextFieldListenerProps {
    eventName: Extract<keyof GlobalEventHandlersEventMap, 'input'>;
    callback(e?: Event): void;
}

然后当我尝试分配此 eventNamecallback 时,出现此错误:

TS2769: No overload matches this call. Overload 1 of 2, '(type: "input" | "blur", listener: (this: HTMLInputElement, ev: Event | FocusEvent) => any, options?: boolean | AddEventListenerOptions | undefined): void', gave the following error. Argument of type '((e?: InputEvent | undefined) => void) | ((e?: FocusEvent | undefined) => void)' is not assignable to parameter of type '(this: HTMLInputElement, ev: Event | FocusEvent) => any'. ...

一开始我想知道如果 eventName'blur' 并且事件是 会不会有问题FocusEvent 所以我创建了一个类型保护器:

export function isBlurTextFieldProps(value: BaseTextFieldListenerProps): value is BlurTextFieldListenerProps {
    return value.eventName === 'blur';
}

并且我更改了负责设置 eventListener 的方法:

public setTextFieldInputListener(listenerProps: TextFieldListenerProps): void {
    if (isBlurTextFieldProps(listenerProps)) {
        this.input.addEventListener(listenerProps.eventName, listenerProps.callback);
    }
}

但这根本没有帮助:/

我的问题是:

  • 为什么会出现此错误?
  • 如何修复它仍然保持强类型? (我知道我可以用 any 解决这个问题,但我不想使用 any

您可以使用通用的 <K>addEventListener 方法来实现。 K指的是事件名称的类型('blur''input')。

public setTextFieldInputListener(listenerProps: TextFieldListenerProps): void {
    if (isOnBlurTextFieldProps(listenerProps)) {
        this.input.addEventListener<'blur'>(listenerProps.eventName, listenerProps.callback.bind(this));
    } else if (isOnInputTextFieldProps(listenerProps)) {
        this.input.addEventListener<'input'>(listenerProps.eventName, listenerProps.callback.bind(this));
    }
}