我试图描述一个事件处理程序的字典(具有不同的有效负载形状),如下所示:
type Events = 'foo' | 'bar';
type EventsPayload = { foo: string, bar: number };
type EventHandler<Event extends Events> = (args: EventsPayload[Event]) => void;
const eventHandlers: { [Event in Events]?: EventHandler<Event> } = {};
export function addEventHandler<Event extends Events>(
name: Event,
handler: EventHandler<Event>,
) {
eventHandlers[name] = handler;
}
这给了我一个错误:
类型“EventHandler”不能分配给类型“{ foo?:EventHandler〈“foo”〉|undefined; bar?:EventHandler〈“bar”〉|undefined; }[事件]'。
如果我在插入处理程序方法时删除泛型,它会起作用:
eventHandlers.foo = (payload: string) => {};
1条答案
按热度按时间8dtrkrch1#
在定义
handler
参数的类型时,可以通过引用eventHandlers
的类型来使其工作。(例如,这就是它们对lib.dom.d.ts
中的addEventListener
所做的。)我发现最简单的方法是为eventHandlers
对象的类型使用类型别名:Playground链接
实际上,你并不需要**来拥有类型别名,但是,你可以使用
typeof eventHandlers
来代替:Playground链接
主观地说,对我来说,如果我们有一个类型别名来工作,那就更清楚了。