我试图extends
在通用参数中使用索引对象,但出现以下错误:
“ IHandlerMap [K]”类型的参数不能分配给“ BasicHandler”类型的参数。输入'BasicHandler | “ KeyPressHandler”不能分配给“ BasicHandler”类型。类型'KeyPressHandler'不能分配给类型'BasicHandler'.ts(2345)
码:
export type BasicHandler = () => void;
export type KeyPressHandler = (keyCode: number) => void;
interface IHandlerMap {
OnTick: BasicHandler;
OnKeyDown: KeyPressHandler;
}
type HandlersType = {[key in keyof IHandlerMap]: IHandlerMap[key][]};
export class EventManager {
private readonly handlers: HandlersType = {
OnTick: [],
OnKeyDown: [],
};
public addHandler<K extends keyof IHandlerMap>(
type: K,
handler: IHandlerMap[K]
): {
this.handlers[type].push(handler); // Error is occuring here.
}
}
看来,TS只能BasicHandler
在可以为BasicHandler
OR时推断出对象属性是类型数组KeyPressHandler
。
如何使用keyof
索引接口(handler: IHandlerMap[K]
),然后使用该参数来推送到也为type
'd(this.handlers[type].push(handler)
?)的对象键?
我在解释我要做什么时遇到很多麻烦,这是做这件事的错误方法吗?如果是这样,有什么替代方法?
我的猜测是,表达式类型this.handlers[type]
触发您的错误:
在addHandler
函数体内,我们不知道两个值"OnTick"
或"OnKeyDown"
属性中的哪个type
,因此假定其基本类型keyof IHandlerMap
或"OnTick" | "OnKeyDown"
属性访问权限。属性访问this.handlers[type]
将解决的类型HandlersType[keyof IHandlerMap]
,这是BasicHandler[] | KeyPressHandler[]
。
现在,当我们调用时this.handlers[type].push
,push
可以使用BasicHandler[]
或调用该方法KeyPressHandler[]
,因此其类型是这两种方法的并集push
:
| (...items: BasicHandler[]): number
| (...items: KeyPressHandler[]): number
从TS 3.3开始,您实际上可以调用联合类型的函数,但是它们的参数是相交的(&
)。该push
签名看起来有点像这样:
(method) Array<T>.push(items: (BasicHandler & KeyPressHandler)[]): number
BasicHandler
没有功能参数,KeyPressHandler
一个。因此,交集导致...没有预期参数。您可以添加一个参数一样s: string
来BasicHandler
和它得到更明显(悬停在push
当时)。
将额外的变量用于this.handlers
typeHandlersTypeMixed
或this.handlers
直接将其用于。注:(BasicHandler | KeyPressHandler)[]
!==
BasicHandler[] | KeyPressHandler[]
。只有前者不会产生联合函数类型,并允许使用push
。操场
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);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句