如何从TypeScript重载函数接口中提取事件名称联合类型?
从重载的
on函数中提取事件名称联合类型 这确实是TypeScript处理重载函数时的一个常见坑——当你直接用infer提取重载函数的参数时,默认只会匹配最后一个重载签名,这就是为什么你只得到了eventName8。下面是解决这个问题的具体方案:
解决方案
我们需要显式地匹配on函数的所有重载签名,把每个重载的参数元组合并成联合类型,再从中提取事件名称:
// 辅助类型:提取重载函数的所有参数元组的联合类型 type GetOverloadArgs<T> = // 匹配8个重载的情况(对应你的IEvents中的on函数) T extends { (...args: infer A): void; (...args: infer B): void; (...args: infer C): void; (...args: infer D): void; (...args: infer E): void; (...args: infer F): void; (...args: infer G): void; (...args: infer H): void; } ? A | B | C | D | E | F | G | H : // 如果重载数量更少,可以继续添加匹配分支 T extends { (...args: infer A): void; (...args: infer B): void; (...args: infer C): void; (...args: infer D): void; (...args: infer E): void; (...args: infer F): void; (...args: infer G): void; } ? A | B | C | D | E | F | G : T extends { (...args: infer A): void; (...args: infer B): void; (...args: infer C): void; (...args: infer D): void; (...args: infer E): void; (...args: infer F): void; } ? A | B | C | D | E | F : never; // 提取IEvents中on函数的所有事件名称联合类型 export type TEventExtension<T extends IEvents> = GetOverloadArgs<T['on']> extends [infer N, ...any[]] ? N : never; // 测试验证 type EventNames = TEventExtension<IEvents>; // EventNames 类型为:'eventName1' | 'eventName2' | 'eventName3' | 'eventName4' | 'eventName5' | 'eventName6' | 'eventName7' | 'eventName8'
为什么之前的方案无效?
你之前的代码中,TEventListenerName<T>的类型推断逻辑:
type TEventListenerName<T> = T extends (name: infer N, listener: (obj?: infer E) => void) => void ? N : never;
只会匹配T的最后一个重载签名。TypeScript的类型系统在处理重载函数时,不会自动将所有重载签名转换为联合类型,所以直接用单一层级的infer只能拿到最后一个重载的参数。
扩展说明
如果外部模块的IEvents中on函数的重载数量发生变化,你只需要调整GetOverloadArgs中的匹配分支层数即可,这个方法不需要复制外部的接口定义,完全基于原接口自动推导。
内容的提问来源于stack exchange,提问作者Pat
相关产品推荐
相关产品推荐

