Typescript 泛型扩展参数不可分配给参数类型

Typescript 泛型扩展参数不可分配给参数类型,typescript,generics,types,typescript-typings,typescript-generics,Typescript,Generics,Types,Typescript Typings,Typescript Generics,我试图在泛型参数中使用extends对对象进行索引,但出现以下错误: “IHandlerMap[K]”类型的参数不能分配给“BasicHandler”类型的参数。 类型“BasicHandler | KeyPressHandler”不可分配给类型“BasicHandler”。 类型“KeyPressHandler”不可分配给类型“BasicHandler”。ts(2345) 代码: 导出类型BasicHandler=()=>void; 导出类型KeyPressHandler=(keyCode:n

我试图在泛型参数中使用
extends
对对象进行索引,但出现以下错误:

“IHandlerMap[K]”类型的参数不能分配给“BasicHandler”类型的参数。 类型“BasicHandler | KeyPressHandler”不可分配给类型“BasicHandler”。 类型“KeyPressHandler”不可分配给类型“BasicHandler”。ts(2345)

代码:

导出类型BasicHandler=()=>void;
导出类型KeyPressHandler=(keyCode:number)=>void;
接口IHandlerMap{
OnTick:BasicHandler;
OnKeyDown:KeyPressHandler;
}
键入HandlersType={[key-in-keyof IHandlerMap]:IHandlerMap[key][]};
导出类事件管理器{
专用只读处理程序:HandlersType={
OnTick:[],
OnKeyDown:[],
};
公共地址处理程序(
类型:K,
处理程序:IHandlerMap[K]
): {
this.handlers[type].push(handler);//此处发生错误。
}
}
似乎只有当对象属性可以是
BasicHandler
KeyPressHandler
时,TS才能推断出该对象属性是
BasicHandler
类型的数组

如何使用
keyof
索引一个接口(
handler:IHandlerMap[K]
),然后使用该参数推送到同样是
type
'd(
this.handlers[type].push(handler)
)的对象键


我在解释我要做的事情时遇到了很多困难,这是错误的做法吗?如果是,还有什么替代方法吗?

我猜,
this.handlers[type]
的表达式类型会触发您的错误:

addHandler
函数体内,我们不知道两个值
“OnTick”
“OnKeyDown”
属性
type
中的哪一个值,因此其基类型
keyof IHandlerMap
“OnTick”|“OnKeyDown”
被假定为属性访问。属性访问
this.handler[type]
将解析为类型
HandlersType[keyof IHandlerMap]
,即
BasicHandler[]| KeyPressHandler[]

现在,当我们调用
this.handlers[type].push
时,
push
方法可以通过
BasicHandler[]
KeyPressHandler[]
调用,因此它的类型是两种
push
方法的联合:

| (...items: BasicHandler[]): number 
| (...items: KeyPressHandler[]): number
从TS 3.3开始,您实际上可以调用a,但它们的参数是相交的(
&
)。推送签名看起来很像:

(method) Array<T>.push(items: (BasicHandler & KeyPressHandler)[]): number

有趣的是,我现在看不到除了断言之外的任何其他方法,比如
any
。我希望@jcalz会检查它。标记为答案。对于其他可能面临类似问题的人,请注意:添加额外变量似乎比直接使用它更好,当我们调用处理程序数组中的函数时直接使用它我们需要正确的类型转换函数。通过使用额外的变量,我们不需要担心类型转换处理函数。
type HandlersTypeMixed = { [key in keyof IHandlerMap]: (BasicHandler | KeyPressHandler)[] }

public addHandler<K extends keyof IHandlerMap>(
    type: K,
    handler: IHandlerMap[K]
) {
    const hs: HandlersTypeMixed  = this.handlers
    hs[type].push(handler);
}