TypeScript 推断函数第一个参数的第二个参数

TypeScript infer second argument of a function first argument

是否可以从另一个参数推断出一个函数参数?我想根据第一个参数的推断来推断第二个参数。

当前代码可以在GitHubslickEventHandler.interface.ts和下面

export type GetSlickEventType<T> =
  T extends (infer U)[] ? U :
  T extends (...args: any[]) => infer U ? U :
  T extends SlickEvent<infer U> ? U : T;

export type GetEventType<T> = T extends infer U ? U : T;

type Handler<H> = (e: SlickEventData, data: GetSlickEventType<H>) => void;

export interface SlickEventHandler<T = any> {
  subscribe: (slickEvent: SlickEvent<T>, handler: Handler<T>) => SlickEventHandler<T>;
  unsubscribe: (slickEvent: SlickEvent<T>, handler: Handler<T>) => SlickEventHandler<T>;
  unsubscribeAll: () => SlickEventHandler<T>;
}

这让我可以执行以下操作(实时代码 here

const onSelectedRowsChangedHandler = this._grid.onSelectedRowsChanged;
(this._eventHandler as SlickEventHandler<GetSlickEventType<typeof onSelectedRowsChangedHandler>>).subscribe(onSelectedRowsChangedHandler, (_e, args) => {
  args.column;
});

这会进行正确的推理

然而,我正在寻找的是一种更简单的方法,如下所示(但我目前使用下面的代码得到的是 args 被推断为 any

this._eventHandler.subscribe(onHeaderCellRenderedHandler, (_e, args) => {
  const column = args.column;
  const node = args.node;
});

所以正如我在问题中提到的那样,为了使它起作用,我需要推断第一个参数并以某种方式创建一个可以由第二个参数使用的别名。最新版本的 TypeScript 可以吗?

我想你希望方法是通用的而不是接口,所以你会把通用放在函数定义而不是接口名称中。

export interface SlickEventHandler {
  subscribe: <T>(slickEvent: SlickEvent<T>, handler: Handler<T>) => this;
  unsubscribe: <T>(slickEvent: SlickEvent<T>, handler: Handler<T>) => this;
  unsubscribeAll: () => this;
}

那么当您调用该方法时将推断出泛型。