繁体   English   中英

如何在 Typescript 中重载和绑定参数类型?

[英]How to overload and bind argument types in Typescript?

我想创建一个 function addEventListener

这个function有两个arguments, eventlistener器。

我有一些特定的事件:例如。 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 类型,例如OnClickOnScroll

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中添加一个新行。

Playground 代码链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM