我目前有一个带有重载函数的接口,如下所示:
export interface IEvents {
method(): boolean;
on(name: 'eventName1', listener: (obj: SomeType) => void): void;
on(name: 'eventName2', listener: (obj: SomeType) => void): void;
on(name: 'eventName3', listener: (obj: SomeType) => void): void;
on(name: 'eventName4', listener: (obj: SomeType) => void): void;
on(name: 'eventName5', listener: (obj: SomeType) => void): void;
on(name: 'eventName6', listener: () => void): void;
on(name: 'eventName7', listener: (obj: SomeType) => void): void;
on(name: 'eventName8', listener: (obj: SomeType) => void): void;
}
我正在尝试获取类似事件名称的联合类型:
eventName1 | eventName2 | ...
我尝试了以下内容,但是当我推断出类型时,它似乎只选择了一个名称值,而不是所有这些名称的联合。
export type TEventExtension<T extends IEvents> {
[K in keyof T]: K extends 'on' ? TEventListenerName<T[K]> : never;
}[keyof T];
export type TEventListenerName<T> = T extends (name: infer N, listener: (obj?: infer E) => void) => void ? N : never;
const ext: TEventExtension<IEvents> = void 0 as any; // Type: 'eventName8'
我也尝试使用累加器类型来跟踪联合,但是Typescript不允许递归泛型。
关于如何实现这一目标的任何想法?
编辑:具有重载定义的接口存在于外部模块中。我试图避免从外部定义到我的定义的c + ping,而是让它自动构建类型。
答案 0 :(得分:1)
这不是一个单独的答案,但很难在评论中得到这个:过载特别是不能以type inference in conditional types的方式工作:
当从具有多个呼叫签名的类型(例如重载函数的类型)推断时,推断是从最后一个签名(可能是最宽容的全部案例)推断出来的。根据参数类型列表无法执行重载决策。
declare function foo(x: string): number; declare function foo(x: number): string; declare function foo(x: string | number): string | number; type T30 = ReturnType<typeof foo>; // string | number
如果您不能将重载转换为具有参数联合的单个函数(使用条件类型来获取listener
"eventName6"
更正),那么我不知道以编程方式执行此操作的方法。
答案 1 :(得分:0)
我认为你不能。使用此示例中的类型推断:
Map<Double, Map<String, Double>> result =
map.entrySet().stream()
.collect(groupingBy(Entry::getValue, toMap(Entry::getKey, Entry::getValue)));
它归咎于x不是无效的,但IEvents中可能的返回类型之一是200.看起来它只尝试使用最新版本。
所以我想如果你尝试用函数的第一个参数做类似的事情,它只会抓住最新的一个。
这里有ReturnType的定义:
https://github.com/Microsoft/TypeScript/blob/release-2.8/lib/lib.d.ts#L1386