简体   繁体   English

打字稿键盘事件:“事件”类型的参数不能分配给“键盘事件”类型的参数

[英]Typescript keyboard event : argument of type 'Event' is not assignable to parameter of type 'KeyboardEvent'

I'have the following error even if the code run perfectly:即使代码运行完美,我也有以下错误:

"TS2345: Argument of type 'Event' is not assignable to parameter of type 'KeyboardEvent'.
  Property 'altKey' is missing in type 'Event'." 

// In a Class

public listenTo = (window: Window) => {
  ['keydown', 'keyup'].forEach(eventName => {
     window.addEventListener(eventName, e => {
       this.handleEvent(e); // <- error here
     });
   });
}

public handleEvent = (event: KeyboardEvent) => {
    const { key } = event;
    //...
}

I tried to define the event type to KeyboardEvent, but I have the following error :我试图将事件类型定义为 KeyboardEvent,但出现以下错误:

 window.addEventListener(eventName, (e:KeyboardEvent) => {
           this.handleEvent(e); // <- error here
         });


 TS2345: Argument of type '(event: KeyboardEvent) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject'.
  Type '(event: KeyboardEvent) => void' is not assignable to type 'EventListenerObject'.
 Property 'handleEvent' is missing in type '(event: KeyboardEvent) => void'.

Is there a way to pass through or resolve the issue ?有没有办法通过或解决问题?

TypeScript isn't able to make the full leap here, because all it knows is the event name will be a string, so the most general event type is used. TypeScript 无法在这里实现全面飞跃,因为它只知道事件名称将是一个字符串,因此使用了最通用的事件类型。

Examples below converted to a stand alone running example - so I've taken things "out of a class" for the demo...下面的示例转换为一个独立的运行示例 - 所以我已经把东西“从课堂上”拿出来进行演示......

While the strings are keydown and keyup you can guarantee the type safety, and overrule the compiler:虽然字符串是keydownkeyup您可以保证类型安全,并否决编译器:

let listenTo = (window: Window) => {
  ['keydown', 'keyup'].forEach(eventName => {
     window.addEventListener(eventName, e => {
       handleEvent(<any>e);
     });
   });
}

let handleEvent = (event: KeyboardEvent) => {
    const { key } = event;
    //...
}

This would fall down if some other string was added to your array of event names.如果将其他一些字符串添加到您的事件名称数组中,这将下降。

Full type safety is available when using a string directly, due to specialized signatures:由于专门的签名,直接使用字符串时可以使用完全类型安全:

  window.addEventListener('keydown', e => {
     handleEvent(e); // e is KeyboardEvent
  });

So you could type your array more strongly to get the correct types goodness:因此,您可以更强烈地键入数组以获得正确的类型优点:

type KeyboardEventNames = 'keydown' | 'keyup';

let listenTo = (window: Window) => {
  const eventNames: KeyboardEventNames[] = ['keydown', 'keyup']; 
  eventNames.forEach(eventName => {
     window.addEventListener(eventName, e => {
       handleEvent(e);
     });
  });
}

let handleEvent = (event: KeyboardEvent) => {
    const { key } = event;
    //...
}

In this last example, we restict the type of elements in the array to only keyboard event names, so the compiler now knows it isn't dealing with just any old string, and can infer the event type.在最后一个示例中,我们将数组中元素的类型限制为仅键盘事件名称,因此编译器现在知道它不仅仅处理任何旧字符串,并且可以推断事件类型。

The strings 'keyup' and 'keydown' are already known string literal types.字符串'keyup''keydown'是已知的字符串文字类型。 However, strings in your code are not candidates for checking against known string literal types unless they are const .但是,代码中的字符串不是检查已知字符串文字类型的候选对象,除非它们是const Simply make yours constant:简单地让你的保持不变:

public listenTo = (window: Window) => {
  ['keydown' as const, 'keyup' as const].forEach(eventName => {
     window.addEventListener(eventName, e => {
       this.handleEvent(e);
     });
   });
}

or要么

public listenTo = (window: Window) => {
  (['keydown', 'keyup'] as const).forEach(eventName => {
     window.addEventListener(eventName, e => {
       this.handleEvent(e);
     });
   });
}

depending on your tastes.取决于你的口味。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “(事件:字符串)=&gt; void”类型的参数不可分配给“EventListenerOrEventListenerObject”类型的参数 - Argument of type '(event: string) => void' is not assignable to parameter of type 'EventListenerOrEventListenerObject “事件”类型的参数不可分配给“CdkDragMove”类型的参数<any> &#39; - Argument of type 'Event' is not assignable to parameter of type 'CdkDragMove<any>' TS2345:“事件”类型的参数不可分配给“HtmlInputEvent”类型的参数 - TS2345: Argument of type 'Event' is not assignable to parameter of type 'HtmlInputEvent' Typescript 错误“类型参数不可分配给类型参数” - Typescript error 'argument of type is not assignable to parameter of type' Typescript:a 类型的参数不能分配给 b 类型的参数 - Typescript: argument of type a is not assignable to parameter of type b TypeScript:类型参数不可分配 - TypeScript: Argument of type is not assignable typescript:类型&#39;any []&#39;的参数不能分配给&#39;[]&#39;类型的参数.ts(2345) - typescript : Argument of type 'any[]' is not assignable to parameter of type '[]'.ts(2345) TypeScript:&#39;Card | 类型的参数 undefined&#39; 不可分配给类型为 &#39;Card&#39; 的参数 - TypeScript: Argument of type 'Card | undefined' is not assignable to parameter of type 'Card' Typescript - 'string | 类型的参数 (string | null)[]' 不能分配给“string”类型的参数 - Typescript - Argument of type 'string | (string | null)[]' is not assignable to parameter of type 'string' 'string | 类型的参数 undefined' 不能分配给'string' 类型的参数。 typescript '严格' - Argument of type 'string | undefined' is not assignable to parameter of type 'string'. typescript 'strict'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM