Invoke a general function with corresponding generic parameters

I am currently working on a function that takes another function and its arguments as parameters, then runs the function with the provided arguments and returns the result while maintaining the data types.

If the function being provided has a fixed return type, everything works smoothly. However, when the return type of the function is dependent on the parameters, I encounter difficulties in preserving the return type.

Below is my unsuccessful attempt which illustrates what I am aiming to achieve:

function f<A>(args: A) {
  return args
}
// Directly calling the function yields the expected output:
const result = f('test') // OK: type of result is 'test'

// I tried to explicitly define the return type but it was not successful
type ReturnTypeWithArgs<
  F extends (args: any) => any,
  A extends Parameters<F>[0],
> = F extends (args: A) => infer R ? R : never

// This is the function I want to create
function callFunction<F extends (args: any) => any, A extends Parameters<F>[0]>(
  f: F,
  args: A,
): ReturnTypeWithArgs<F, A> {
  return f(args)
}

// My goal is to have the same return type when using callFunction. Unfortunately, it does not work as intended:
const result2 = callFunction(f, 'test') // KO: typeof test2 is unknown

Answer №1

At this moment, there isn't a purely type-level method to determine the return type of a generic function when provided with a specific argument type. Using conditional type inference doesn't yield the desired result as it replaces generic type parameters with their constraints.

An open suggestion has been made for type operators that would address this issue, but it is currently marked as "Awaiting More Feedback" on GitHub without significant engagement from the community. However, users can show support by visiting the link and explaining the need and use case for such functionality.


In TypeScript, manipulating higher order generics typically involves incorporating value-level code that translates to JavaScript during compilation. A workaround involves creating a separate generic function to achieve the desired type manipulation, as demonstrated in the implementation detailed in microsoft/TypeScript#30215.

function callFunction<A, R>(f: (arg: A) => R, args: A): R {
    return f(args)
}
const result = callFunction(f, 'test') // string

This approach leads to obtaining the actual input type, like 'string', instead of just 'unknown'.


Note that there might be instances where inferred types may not match the expected literal type due to limitations in TypeScript's inference mechanism. In such cases, hints or workarounds can assist in achieving the correct narrower types, as shown in the example involving the Narrowable hint type constraint.

type Narrowable = string | number | boolean | null | undefined | bigint | {};
function callFunction<A extends Narrowable, R>(
    f: (arg: A) => R,
    args: A,
): R {
    return f(args)
}
const result2 = callFunction(f, 'test') // "test"

Link to Playground

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

Creating anchor links with #id that function correctly in an Angular project can sometimes be challenging

My backend markdown compiler generates the HTML content, and I need Angular to retrieve data from the server, dynamically render the content, and display it. An example of the mock markdown content is: <h1 id="test1">Test 1<a href="#test1" title ...

Can anyone provide guidance on setting up a TypeScript service worker in Vue 3 using the vite-plugin-pwa extension?

I am looking to develop a single-page application that can be accessed offline. To achieve this, I have decided to implement a PWA Service Worker in my Vue webapp using TypeScript and Workbox. I found useful examples and guidance on how to do this at . Ho ...

Refresh the information in the <ion-datetime> component by utilizing the formGroup

I am currently working with a form that has been created using 'FormBuilder'. The form includes a date control and I am trying to figure out how to update the data in that control using the patchValue() method. In the template, the control has d ...

Retrieve a collection within AngularFire that includes a subquery

I have the following function getParticipations( meetingId: string ): Observable<Participation[]> { return this.meetingCollection .doc(meetingId) .collection<ParticipationDto>('participations') .snapshotCh ...

Using TypeScript to import a Vue 2 component into a Vue 3 application

Recently, I embarked on a new project with Vue CLI and Vite, utilizing Vue version 3.3.4 alongside TypeScript. In the process, I attempted to incorporate the vue-concise-slider into one of my components. You can find it here: https://github.com/warpcgd/vu ...

Error caused by properties of a variable derived from an interface in the compiler

I'm confused as to why the compiler is saying that the properties "name" and "surname" don't exist on type "ITest1" within function test1. It's a bit unclear to me: interface ITest1{ name: string; surname: string; age: number; } ...

Transform Material UI Typography to css-in-js with styled-components

Can Material UI elements be converted to styled-components? <Container component="main" maxWidth="XS"> <Typography component="h1" variant="h5"> Sign in </Typography> I attempted this for typography but noticed that t ...

Implementing individual NGRX Selectors for each child component to enable independent firing

My component serves as a widget on a dashboard, and I am using *ngFor to render multiple widgets based on the dashboard's data. Each WidgetComponent receives some of its data via @Input() from the parent. parent <app-widget *ngFor="let widget ...

Dropdown Pattern with React CTA Modal

While using MaterialUI's ButtonGroup for a dropdown menu, I encountered an issue trying to set up a series of CTAs that are easily interchangeable within it. The goal is to have all components reusable and the choices in the dropdown dynamic. const C ...

leveraging the import statement in conjunction with SystemJs

Currently, I am in the process of creating a sample code using TypeScript and SystemJS for the browser. In my app.ts file: import {Person,add as test} from './testLib' In the generated app.js file (by TypeScript compiler): var testLib_1 = re ...

Warning: The gulp_jspm module is now deprecated and will be removed

Whenever I run gulp_jspm, a DeprecationWarning pops up. Is there an alternative method to generate my bundle files without encountering this warning? It seems like when I used gulp-jspm-build, I had to include some node files that were not necessary before ...

Leveraging the ngFor local variable within nested elements

Is there a way to properly display a property of the local variable theme, such as theme.name? Below is an example of how my *ngFor is structured: <ul> <li *ngFor="#theme of themes"> <span>theme.name</span> </li> ...

Enhance the capabilities of a basic object by incorporating a superclass through the creation of

I'm currently developing a library using Typescript 2.0 that can be utilized from both Typescript and JavaScript. Within the library, there is a class called Component and a function named registerComponent, both written in Typescript. My goal is to ...

SwitchMap in Typescript allows you to switch to a

In my TypeScript code, I have implemented multiple interfaces, components, and a key/interface map. interface FooProps { 'keyInFoo': string } const Foo = (props: FooProps) => {} interface BarProps { 'keyInBar': string } cons ...

Unveiling the Mystery of Angular: Why are constructor parameters without access specifiers hidden from view outside the

When I explicitly set an access specifier for a constructor parameter, it becomes visible outside the constructor. For example: constructor(private employeResourceService:EmployeeResourceService ){ //code} ngOnInit(){ this.employeResourceService=unde ...

Expanding TypographyProps and TextFieldProps for enhanced functionality

Currently, I am developing a React component using TypeScript along with Material UI (MUI). The main purpose of this component is to display either an input field or text based on the mode selected. To switch between these modes, the prop mode is utilize ...

To ensure the specificity selector for material UI in React, it is essential to include an empty CSS definition

The styling for the unselected toggle button is working smoothly. However, when you don't define an empty class selector, the style of the selected toggle button does not show: ./App.js import * as React from "react"; { render ...

What could be the reason it's not functioning as expected? Maybe something to do with T extending a Record with symbols mapped

type Check<S extends Record<unique, unknown>> = S; type Output = Check<{ b: number; }>; By defining S extends Record<unique, unknown>, the Check function only accepts objects with unique keys. So why does Check<{b:number}> ...

Leveraging a Derived-Class Object Within the Base-Class to Invoke a Base-Class Function with Derived-Class Information

I have a situation where I need to access a method from a derived class in my base generic component that returns data specific to the derived class. The first issue I encountered is that I am unable to define the method as static in the abstract class! ...

Retrieving a variable value set within a jQuery function from within an Angular 2 component

In the current project, I am facing a situation where I need to work around and initialize jQuery datetimepicker inside an Angular 2 application (with plans to refactor it later). However, when I assign a datetime value to a variable, I encounter a proble ...