Можно ли ввести или привести значения string[] в качестве ключа WindowEventMap?

#typescript

Вопрос:

Можно ли ввести или привести типы событий для работы со следующим сценарием?

Можно ли это сделать, если типы событий были подмножеством keyof WindowEventMap ?

 const EventTypes = [
    "abort",
    ...
    "mouseenter",
    "mouseleave",
    ....
];  //A list of all keyof WindowEventMap strings

function consumeEvent<K extends keyof WindowEventMap>( eventType: keyof WindowEventMap, ev: WindowEventMap[K] ) {
    ....
}

EventTypes.forEach( et => window.addEventListener( et, e => consumeEvent( et, e)));
//`et` causes an error as a parameter to consumeEvent
//Argument of type 'string' is not assignable to parameter of type 'keyof WindoEventMap'
 

Ответ №1:

В приведенном выше примере вы делаете так, как предлагали, и приводите тип массива в виде списка ключей WindowEventMap , а не произвольного string[] (придирайтесь, camelCase ваш массив, потому что заглавные буквы делают его похожим на тип.)

 const events = [
  'abort',
  'mouseenter',
  'mouseleave',
] as (keyof WindowEventMap)[];

function consumeEvent<K extends keyof WindowEventMap>(
  eventType: K,
  ev: WindowEventMap[K],
) {}

events.forEach((et) => window.addEventListener(et, (e) => consumeEvent(et, e)));
 

Если вы хотите ограничить функцию, разрешив только подмножество типов событий, вы можете объявить подмножество с помощью Extract :

 type AllowedEvent = Extract<
  keyof WindowEventMap,
  'abort' | 'mouseenter' | 'mouseleave'
>;

function consumeEvent<K extends AllowedEvent>(
  eventType: K,
  ev: WindowEventMap[K],
) {}

const events = [
  'abort',
  'mouseenter',
  'mouseleave',
] as AllowedEvent[];

events.forEach((et) => window.addEventListener(et, (e) => consumeEvent(et, e)));