打字稿推断函数参数联合

Pat*_*Pat 6 javascript typescript typescript-typings

我目前有一个带有重载函数的接口,如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

我试图得到这样的联合类型的事件名称:

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'
Run Code Online (Sandbox Code Playgroud)

我也尝试使用累加器类型来跟踪联合,但Typescript不允许递归泛型.

有关如何实现这一目标的任何想法?

编辑:具有重载定义的接口存在于外部模块中.我试图避免从外部定义到我的定义的c + ping,而是让它自动构建类型.

lil*_*zek 0

我认为你不能。在此示例中使用类型推断:

interface SomeType {

}

export interface IEvents {
  method(): boolean;
  on(name: "eventName1", listener: (obj: SomeType) => void): 13;
  on(name: "eventName2", listener: (obj: SomeType) => void): void;
  on(name: "eventName3", listener: (obj: SomeType) => void): undefined;
  on(name: "eventName4", listener: (obj: SomeType) => void): 14;
  on(name: "eventName5", listener: (obj: SomeType) => void): 10;
  on(name: "eventName6", listener: () => void): "hola";
  on(name: "eventName8", listener: (obj: SomeType) => void): 200;
  on(name: "eventName7", listener: (obj: SomeType) => void): void;
}

const x: ReturnType<IEvents["on"]> = 200;
Run Code Online (Sandbox Code Playgroud)

它指责 x 不是 void,但 IEvents 中 on 的可能 ReturnType 之一是 200。看起来它只尝试使用最新的类型。

所以我想,如果您尝试对函数的第一个参数执行类似的操作,它只会获取最新的参数。

这里有 ReturnType 的定义:

https://github.com/Microsoft/TypeScript/blob/release-2.8/lib/lib.d.ts#L1386