簡體   English   中英

TypeScript - 如何在此代碼中注釋類型?

[英]TypeScript - How to annotate types in this code?

我正在我的庫中編寫一個可以注冊一堆用戶提供的事件偵聽器的方法。 這是一個簡化的示例:

function registerEventListeners(events: Record<string, EventListenerOrEventListenerObject>): void {
  for (const [name, handler] of Object.entries(events)) {
    window.addEventListener(name, handler)
  }
}

const customEvents = {
  keydown: (e: KeyboardEvent) => {
    if (e.key === "Enter") {
      // ...
    }
  }
}

registerEventListeners(customEvents)

TypeScript 在registerEventListeners的調用站點給我這個錯誤......

~      1. Argument of type '{ keydown: (e: KeyboardEvent) => void; }' is not assignable to parameter of type 'Record<string, EventListenerOrEventListenerObject>'.
~           Property 'keydown' is incompatible with index signature.
~             Type '(e: KeyboardEvent) => void' is not assignable to type 'EventListenerOrEventListenerObject'.
~               Type '(e: KeyboardEvent) => void' is not assignable to type 'EventListener'.
~                 Types of parameters 'e' and 'evt' are incompatible.
~                   Type 'Event' is missing the following properties from type 'KeyboardEvent': altKey, charCode, code, ctrlKey, and 17 more.

EventListenerOrEventListenerObject泛型似乎無法保證我的 keydown 事件處理程序將接收正確的事件類型。 那么輸入此代碼的正確方法是什么?

正如我的評論所述,您正在這樣做:

(event: Event) => void;         // defined type
        |                       // lying to the given type
        V                       // by passing any event to it
(event: KeyboardEvent) => void; // given type

但是,您可以使用這種折衷方案,為//@ts-ignore犧牲一行,但獲得最終用戶的預期行為。 本質上,您現在期望事件名稱的 map 指向正確的事件類型,而不是通用事件類型的任何字符串。

function registerEventListeners(events: Partial<{
    [K in keyof WindowEventMap]: (event: WindowEventMap[K]) => void;
}>): void {
  for (const [name, handler] of Object.entries(events)) {
    //@ts-ignore
    window.addEventListener(name, handler);
  }
}

const customEvents = {
  keydown: (e: KeyboardEvent) => {
    if (e.key === "Enter") {
      // ...
    }
  }
}

registerEventListeners(customEvents)

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM