[英]The const assertion seems that the type can't be assigned to the type any[] for the generic parameter
[英]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.