Typescript 泛型类型的查找类型可以';不能分配给;任何;

Typescript 泛型类型的查找类型可以';不能分配给;任何;,typescript,Typescript,好吧,这个有点难以解释。我的例子很复杂,但我尽量简化它,同时保留错误 type处理程序=(…参数:any[])=>void; 常量处理程序:{[eventName:string]:Handler}={}; 类型事件={ //将事件签名(参数类型)映射到事件名称 [eventName:string]:任意[]; }; 函数createOneEvent(){ 键入ValidEventName=Extract; 返回( eventName:eventName, eventHandler:(…参数:Us

好吧,这个有点难以解释。我的例子很复杂,但我尽量简化它,同时保留错误

type处理程序=(…参数:any[])=>void;
常量处理程序:{[eventName:string]:Handler}={};
类型事件={
//将事件签名(参数类型)映射到事件名称
[eventName:string]:任意[];
};
函数createOneEvent(){
键入ValidEventName=Extract;
返回(
eventName:eventName,
eventHandler:(…参数:UserEvents[EventName])=>void,
) => {
处理程序[eventName]=eventHandler;//[0]此处出现错误
};
}
[0]类型“any[]”不能分配给类型“UserEvents[EventName]”

有两件事让我困惑:

  • UserEvents[EventName]
    应等于
    any[]
  • 我试图将
    UserEvents[EventName]
    分配给
    any[]
    ,而不是相反
顺便说一句,这个API是如何使用的:

类型FooEvents={
事件一:[数字];
eventTwo:[字符串,布尔值];
};
const onEvent=createOnEvent();
OneEvent('eventOne',(arg1:number)=>null);//好啊
onEvent('eventTwo',(arg1:string,arg2:boolean)=>null);//好啊
OneEvent('eventOne',(arg1:string)=>null);//错误
这和预期的一样。唯一失败的部分是当我想将处理程序存储在
handlers
中时,这应该是包含任何参数列表的函数


我意识到这有点混乱,所以如果我能澄清任何事情,请告诉我。我很想弄清这件事的真相。谢谢

原因

您遇到的错误源于这样一个事实:当使用
--strictFunctionTypes
标志时,函数类型为

这是什么意思?这意味着当函数要求其参数使用某种类型时,您可以将参数作为特定类型或比预期类型更宽的类型使用

在您的例子中,
处理程序
是泛型处理程序的字典。这些处理程序需要
任何[]
参数。他们的定义也可以这样写:

const handlers: {
  [eventName: string]: (...args: any[]) => void
} = {};
但是,您的
eventHandler
不仅仅是一个通用处理程序。它不仅接受
任何[]
参数,还接受
UserEvents
描述的一些非常具体的参数。这与逆变的思想背道而驰——传递给函数的参数不能比其签名所需的参数更具体。换句话说,
typeofeventhandler
不能分配给
Handler

你能做什么

  • 通过使用类型断言在本地扩展
    eventHandler
    的类型:

    handlers[eventName] = eventHandler as Handler;
    
  • 使编译器接受处理程序的特定定义:

    type Handler<T extends any[] = any> = (...args: T) => void;
    
    type处理程序=(…args:T)=>void;
    

您使用的是哪个版本的TypeScript?使用TypeScript 3.2.1时它不会出错。@KarolMajewski该错误似乎只在使用
--strictFunctionTypes
标志时发生。如果你明白原因,请告诉我。我启用了
strict
,但我不知道这个标志的含义是什么……啊,是的!我总是忘记在操场上挂国旗<代码>--strictFunctionTypes负责适当的协方差和逆变换。这篇博文很好地解释了它是什么: