[英]How to overload and bind argument types in Typescript?
我想创建一个 function addEventListener
这个function有两个arguments, event
和listener
器。
我有一些特定的事件:例如。 在onClick
onScroll
onDoubleClick
。
根据event
,我希望为listener
器参数提供单独的签名/类型。
因此,如果我开始输入:
addEventListener('onClick', (param: OnClickType) => // here I want to resolve a certain listener type )
// or
addEventListener('onScroll', (param: OnScrollType) => // here I want to resolve a certain listener type )
这在 typescript 中是否可行?
[编辑]
像这样的东西:
[编辑2]
export type OnClick = (event: 'onclick', listener: (x: number) => void) => void
export type OnScroll = (event: 'onscroll', listener: (x: string) => void) => void
export type EventListener = OnClick | OnScroll;
const addEventListener: EventListener = (ev, ls) => {
console.log(ev, ls);
return;
}
addEventListener('onclick', )
我想要的是根据第一个参数( event
)的值来推断 function ( listener
)的第二个参数的类型。
如果您只有几个硬编码的 function 类型,例如OnClick
和OnScroll
:
type OnClick = (event: 'onclick', listener: (x: number) => void) => void
type OnScroll = (event: 'onscroll', listener: (x: string) => void) => void
并且您想说EventListener
的行为可以像所有这些一样,您可以手动将两个调用签名重写为单个重载的 function 类型:
type EventListener = {
(event: 'onclick', listener: (x: number) => void): void;
(event: 'onscroll', listener: (x: string) => void): void;
}
const addEventListener: EventListener = (ev, ls) => {
console.log(ev, ls);
return;
}
addEventListener('onclick', x => console.log(x.toFixed(2))); // okay
addEventListener('onscroll', x => console.log(x.toUpperCase())); // okay
等效地,您可以将EventListener
编写为现有 function 类型的交集:
type EventListener = OnClick & OnScroll;
这将两个调用签名置于同一类型,作为重载的 function 类型,首先具有OnClick
签名,然后是OnScroll
签名。 因此,当您调用EventListener
时,编译器将首先尝试解析OnClick
调用签名,如果失败则回退到OnScroll
。 由于"onclick"
和"onscroll"
是互斥的,所以顺序在这里并不重要。 但是在某些情况下,调用签名解析的顺序确实很重要,然后类型F1 & F2
的行为将与F2 & F1
不同(这可能令人惊讶,因为交叉点在概念上是无序的)。
如果您有一堆不同的事件名称和有效负载类型,并且您不想为每个这样的对手动写出一个调用签名,您可以放弃多调用签名重载,转而使用单个通用function:
interface EventMap {
onclick: number;
onscroll: string;
}
type EventListener = <E extends keyof EventMap>(
event: E, listener: (x: EventMap[E]) => void
) => void;
这行为类似(之前的实现和对addEventListener()
的调用仍然有效),但现在您可以为每个新的事件名称/有效负载类型对在EventMap
中添加一个新行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.