簡體   English   中英

來自泛型類型的查找類型不能分配給“任何”

[英]Lookup type from generic type can't be assigned to “any”

好吧,這個有點難以解釋。 我的例子很復雜,但我試圖盡可能地簡化它,同時保留錯誤。

type Handler = (...args: any[]) => void;

const handlers: { [eventName: string]: Handler } = {};

type Events = {
  // Map event signature (arg types) to event name
  [eventName: string]: any[];
};

function createOnEvent<UserEvents extends Events>() {
  type ValidEventName = Extract<keyof UserEvents, string>;

  return <EventName extends ValidEventName>(
    eventName: EventName,
    eventHandler: (...args: UserEvents[EventName]) => void,
  ) => {
    handlers[eventName] = eventHandler; // [0] ERROR HERE
  };
}

[0]類型'any []'不能分配給'UserEvents [EventName]'

有兩件事令我困惑:

  • UserEvents[EventName]應該等於any[]
  • 我正在嘗試將UserEvents[EventName]分配給any[] ,而不是相反...

順便說一下,這是這個API的使用方式:

type FooEvents = {
  eventOne: [number];
  eventTwo: [string, boolean];
};

const onEvent = createOnEvent<FooEvents>();
onEvent('eventOne', (arg1: number) => null); // OK
onEvent('eventTwo', (arg1: string, arg2: boolean) => null); // OK
onEvent('eventOne', (arg1: string) => null); // error

哪個按預期工作。 失敗的唯一部分是當我想將處理handlers存儲在處理handlers ,它應該期望具有任何args列表的函數。

我意識到這有點令人困惑,所以如果我能澄清任何事情,請告訴我。 我很高興能夠深究這一點。 謝謝!

原因

您遇到的錯誤源於這樣的事實:當使用--strictFunctionTypes標志時,函數類型在其參數類型中是逆變的

這意味着什么? 這意味着當函數期望其參數具有某種類型時,您可以使用特定參數或比預期類型更寬的參數。

在您的情況下, handlers是通用處理程序的字典。 這些處理程序期望any[]參數。 他們的定義也可以寫成:

const handlers: {
  [eventName: string]: (...args: any[]) => void
} = {};

但是,您的eventHandler不僅僅是一個通用的處理程序。 它不接受any[]參數,而是接受UserEvents描述的一些非常具體的參數。 這違背了逆向的觀點 - 傳遞給函數的參數不能比其簽名所要求的更具體。 換句話說, typeof eventHandler不能分配給Handler

你可以做什么

  • 通過使用類型斷言在本地eventHandler的類型:

     handlers[eventName] = eventHandler as Handler; 
  • 使編譯器接受處理程序的特定定義:

     type Handler<T extends any[] = any> = (...args: T) => void; 

暫無
暫無

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

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