Невозможно передать eventName и обратный вызов в addEventListener из-за «Нет перегрузки, соответствующей этому вызову» - PullRequest
0 голосов
/ 01 августа 2020

Я пытаюсь добавить прослушиватель событий к элементу ввода, хранящемуся внутри класса, в методе этого класса, который принимает объект props, содержащий eventName и callback.

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

Этот объект реквизита слушателя представляет собой тип объединения двух интерфейсов BlurTextFieldCallbackProps InputTextFieldCallbackProps

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;
}

Затем, когда я пытаюсь чтобы назначить это eventName и callback, я получаю эту ошибку:

TS2769: этому вызову не соответствует никакая перегрузка. Перегрузка 1 из 2, '(type: "input" | "blur", listener: (this: HTMLInputElement, ev: Event | FocusEvent) => any, options ?: boolean | AddEventListenerOptions | undefined): void', дал следующее ошибка. Аргумент типа '((e ?: InputEvent | undefined) => void) | ((e ?: FocusEvent | undefined) => void) 'не может быть назначен параметру типа' (this: HTMLInputElement, ev: Event | FocusEvent) => any '. ...

Вначале мне было интересно, что это может быть проблемой, если eventName будет 'blur', а событие будет FocusEvent поэтому я создал typeguard:

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)

1 Ответ

0 голосов
/ 16 августа 2020

Этого можно добиться, используя метод generi c <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));
    }
}
...