简体   繁体   中英

TypeScript infer second argument of a function first argument

Is it possible to infer a function argument from another argument? I want to infer 2nd argument based on inference of 1st argument.

Current code

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>;
}

and this allows me to do the following

const onHeaderCellRenderedHandler = this.grid.onHeaderCellRendered;
(this._eventHandler as SlickEventHandler<GetSlickEventType<typeof onHeaderCellRenderedHandler >>).subscribe(onHeaderCellRenderedHandler , (e, args) => {
  args.column;
});

and this does proper inference

在此处输入图片说明

However, what I really wish to do is through a much simpler approach shown below (however below args is infered as any )

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

So as I mentioned in the question, for that to work, I would need to infer first argument and somehow make an alias that can be used by the second argument. Is that possible with latest version of TypeScript?

I think you want the methods to be generic not the interface, so you would put the generic at the function definition not the interface name.

export interface SlickEventHandler {
  subscribe: <T>(slickEvent: SlickEvent<T>, handler: Handler<T>) => SlickEventHandler<T>;
  unsubscribe: <T>(slickEvent: SlickEvent<T>, handler: Handler<T>) => SlickEventHandler<T>;
  // it is unclear how you would expect a generic to be actually typed on unsubscribeAll
  unsubscribeAll: () => SlickEventHandler<unknown>;
}

then the generic will be inferred when you call the method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM