Determine the second parameter of a TypeScript function based on the first parameter

Can a function argument be inferred from another argument? I'm interested in inferring the 2nd argument based on the inference of the 1st argument.

The current code can be found on GitHub at slickEventHandler.interface.ts and appears as follows:

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

This setup allows me to do the following (see live code here):

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

And this implementation provides correct inference.

https://i.sstatic.net/m9tUE.png

However, I am seeking a simpler approach as shown below (though currently using the code below results in args being inferred as any):

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

Therefore, to achieve that, I would need to infer the first argument and create some kind of alias that can be utilized by the second argument. Is this achievable with the latest version of TypeScript?

Answer №1

To ensure the methods are generic, it would be best to place the generic at the function definition instead of the interface name.

export interface CustomEventHandler {
  addListener: <T>(eventName: EventName<T>, callback: Callback<T>) => this;
  removeListener: <T>(eventName: EventName<T>, callback: Callback<T>) => this;
  removeAllListeners: () => this;
}

By following this approach, the generic type will be automatically determined when you invoke the method.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Challenges with TypeScript's typeof operator and instantiation of classess

Discussing the scenario of a map setup: const map = { a: ClassA, b: ClassB, c: ClassC, } The purpose of this map is to link different classes together. There exists a function that returns an instance of a class based on a key in the map ...

Remove the array stored in the local storage of an Ionic 2 application

In my application, I store data in a string. To convert the data into arrays, I use JSON.parse. this.items = JSON.parse(todos); On the results page, I display my arrays as follows: Array1 Array2 Array3 However, I have noticed that the delete button aft ...

Convert an array of objects into a singular object while preserving data types in TypeScript

I have an array filled with objects containing keys name and value. My goal is to merge these objects into a single object, where the keys correspond to the name property and the values correspond to the value property of the input objects. type Input = { ...

When trying to map a nullish object, TypeScript throws an error

When I try to map a nullish object, I encounter an error: Object is possibly 'undefined'.ts(2532) Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Partial<Point ...

Mastering the proper implementation of the factory method in TypeScript

Trying to articulate this question is proving to be a challenge, but I'll give it my best shot. In Sharepoint, a default ListItem comes with properties like id, title, createdby, createddate, modifiedby, and modifieddate. Custom lists can have addit ...

Tips for updating a service variable value within a component

My goal is to pass user input to the deviceName string in my component, which should then be passed to the deviceIP string in my service. It seems like the order of using get/set methods might be incorrect. Can someone help me identify the mistake? Below ...

A Step-by-Step Guide on Including TypeScript Definitions in .NET Core Nuget Packages

Our internal NuGet Package includes both .NET Code and a TypeScript Definition File (*.d.ts). Here is what the package contains: https://i.sstatic.net/7vRxx.png Upon installation of the package into a new .NET Core project, the solution explorer displays ...

Resolving the Challenge of Disabling typescript-eslint/typedef in Angular 13 with ESlint

I started a fresh project in Angular 13 and configured typescript-eslint by running the command below: ng add @angular-eslint/schematic I made changes to my .eslintrc.json file where I disabled the rules for "typescript-eslint/typedef" and "typescript-esl ...

Assigning variables within Redux saga generators/sagas

Consider this scenario: function* mySaga(){ const x = yield call(getX) } The value of const x is not determined directly by the return value of call(getX()). Instead, it depends on what is passed in mySaga.next(whatever) when it is invoked. One might a ...

Managing the re-rendering in React

I am encountering a situation similar to the one found in the sandbox example. https://codesandbox.io/s/react-typescript-fs0em My goal is to have Table.tsx act as the base component, with the App component serving as a wrapper. The JSX is being returned ...

Convert a generic observable list to a generic list

Can an array containing [Observable<string>, Observable<number>] be converted to [string, number] using generics? function example(obs: Observable<any>[]): any[] { } Intended Outcome: example(of(''), of(0)) // should return [st ...

What is the process for using infer to determine the return type of a void function?

I am trying to gain a better understanding of how to utilize the infer keyword in TypeScript. Is this an appropriate example demonstrating the correct usage of infer? I simply want to infer the return type of the function below: const [name, setName] = u ...

Learn the process of extracting and displaying specific key-value pairs from a JSON array post-conversion from CSV to JSON using NodeJS and TypeScript

As a newcomer to the world of Javascript and Typescript, I am currently learning on the job. I have a CSV file that I successfully parsed using this helpful resource https://www.npmjs.com/package/csv-parser. The output after parsing is an array of JSON key ...

Reactjs - The createStore function is unable to identify the reducer when TypeScript is being used

I recently delved into the world of Reactjs and Typescript and attempted to create a todo item project. However, I encountered an error in VSCode when trying to call createStore that I am struggling to resolve. Any assistance on this matter would be great ...

NestJS RabbitMQ Microservice Integration

Currently, I am attempting to establish a connection to a Rabbit MQ docker container through NestJS microservice. The setup involves running it using vagrant. Unfortunately, I keep encountering the following error: [1601171008162] ERROR (32761 on local): D ...

Typescript's mock function allows developers to create mock implementations of

Here is the code that needs to be mocked: const P = { scripts: { getScripts: (name?: any) => { // do some stuff and return json return { foo: 'value'}; } } } export default P; The code needing ...

Is it feasible to determine the precise class of an object while utilizing a variable that possesses a union type in Typescript?

Currently delving into Typescript and running tests. Upon using console.log, I received an object. Given its typed nature, I anticipated it to accurately determine the type of variable c. interface Car { gears: number } interface Bike{ gears: number ...

Unable to determine the data type of the property within the table object

Is it feasible to retrieve the type of object property when that object is nested within a table structure? Take a look at this playground. function table<ROW extends object, K extends Extract<keyof ROW, string>>({ columns, data, }: { col ...

styled-jsx fails to dynamically apply styles

Issue with Styling in GridTile Component: The style inside the GridTile component is not being applied properly. No errors or warnings observed in vscode, webpack has compiled successfully and browser console shows no errors. import React, { useState, u ...

Cleaning up HTML strings in Angular may strip off attribute formatting

I've been experimenting and creating a function to dynamically generate form fields. Initially, the Angular sanitizer was removing <input> tags, so I discovered a way to work around this by bypassing the sanitation process for the HTML code stri ...