[英]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.