TypeScript双重泛型问题:Listener类型为何提示‘非泛型’错误
TypeScript泛型函数类型报错:Type 'Listener' is not generic
先看报错的代码:
type ListenerShape< EventType extends string, EventTypeMapData extends { [key in EventType]: unknown; } > = <E extends EventType>(data: EventTypeMapData[E]) => void; enum EventType { A = 'a', B = 'b', } type EventTypeMapData = { [EventType.A]: number, [EventType.B]: string, } type Listener = ListenerShape<EventType, EventTypeMapData>; type AListener = Listener<EventType.A>; // 此处报错:Type 'Listener' is not generic
问题原因
ListenerShape是一个泛型类型,它接受EventType和EventTypeMapData两个参数后,返回的是一个泛型函数类型。但当你把ListenerShape<EventType, EventTypeMapData>赋值给Listener时,TypeScript会直接解析出这个泛型函数的具体类型——此时Listener已经是一个确定的函数类型(不再是泛型函数类型),自然无法再传入EventType.A这样的泛型参数。
解决方案
根据需求不同,有两种常见的处理方式:
方式一:调整泛型参数层级,把事件类型作为外层泛型参数
如果需要给特定事件类型定义监听器,可以把E(具体事件类型)提升为ListenerShape的外层泛型参数:
type ListenerShape< EventType extends string, EventTypeMapData extends { [key in EventType]: unknown }, E extends EventType > = (data: EventTypeMapData[E]) => void; enum EventType { A = 'a', B = 'b', } type EventTypeMapData = { [EventType.A]: number, [EventType.B]: string, } // 直接传入具体事件类型来定义监听器 type AListener = ListenerShape<EventType, EventTypeMapData, EventType.A>;
方式二:直接使用泛型函数类型,跳过中间的Listener定义
如果需要保留原有的泛型函数结构,不需要先定义Listener,直接针对特定事件类型推导:
type ListenerShape< EventType extends string, EventTypeMapData extends { [key in EventType]: unknown } > = <E extends EventType>(data: EventTypeMapData[E]) => void; enum EventType { A = 'a', B = 'b', } type EventTypeMapData = { [EventType.A]: number, [EventType.B]: string, } // 直接定义对应事件A的监听器类型 type AListener = (data: EventTypeMapData[EventType.A]) => void;
内容的提问来源于stack exchange,提问作者Mebtte
相关产品推荐
相关产品推荐

