How can I determine the return type for a specific set of parameters in a generic function?

I have a requirement to develop a utility type that can take the signature of a generic function along with its arguments. The goal is to determine the return type of the signature as if it were called with those specific arguments.

My initial attempt:

type GetReturnType<T extends (...args: any) => any, B> = T extends (...args: any) => infer R ? R : never;

However, all generics seem to end up being either unknown or never.

Here are a few sample functions that might be passed in:

function myFn1<T>(x: T) {
    return {
        a: x,
    }
}

function myFn2<T>(x: T) {
    return [x];
}

function myFn3<T>(x: T) {
    if (typeof x == "string") {
        return "yes" as (T extends string ? "yes" : "no");
    } else {
        return "no" as (T extends string ? "yes" : "no");
    }
}

And here's how I envision using the GetReturnType:

type Return1 = GetReturnType<typeof myFn1, [x: number]>; // expected {a: number}
type Return2 = GetReturnType<typeof myFn2, [x: number]>; // expected number[]
type Return3A = GetReturnType<typeof myFn3, [x: number]>; // expected "no"
type Return3B = GetReturnType<typeof myFn3, [x: string]>; // expected "yes"

Playground link

While TypeScript has a mechanism for inferring generic types in functions, such as myFn3("some string") inferring the first generic argument as a string and returning "yes", I would like to leverage this system when determining the return type. Some queries on Stack Overflow discuss achieving this with known generics, but I am interested in doing so with inferred generics.

Answer №1

const createObject = <A>(value: A) => ({ value } as const);

type ObjectCreator<A> = ReturnType<typeof createObject<A>>;

const convertArrayToObject = <A extends unknown[]>(value: readonly [...A]) => value.map(createObject) as {
  [K in keyof A]: ObjectCreator<A[K]>;
};


type t2 = ReturnType<typeof convertArrayToObject<["a", "b", "c"]>>;
// type t2 = [{
//   readonly value: "a";
// }, {
//   readonly value: "b";
// }, {
//   readonly value: "c";
// }]

I believe this is the closest solution we can achieve with current limitations. It would be ideal to pass createObject as a parameter, but unfortunately, that's not possible as far as I know.

Answer №2

Why is it possible for me to return additional information with the same question?

type RX = { id: number; name: string };
type GetProduct = (name: string) => RX;

const getProduct: GetProduct = (name) => ({ id: 123, name, city: "" });

Such as including the City field in the response.

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

What is the best way to get my Discord bot to respond in "Embed" format using TypeScript?

I've been attempting to create a bot that responds with an embedded message when mentioned, but I'm running into some issues. Whenever I run this code snippet, it throws an error in my terminal and doesn't seem to do anything: client.on(&apo ...

Angular developers are struggling to find a suitable alternative for the deprecated "enter" function in the drag and drop CDK with versions 10 and above

By mistake, I was working on an older version of Angular in StackBlitz (a code-pane platform). I came across a function called enter on GitHub, but it didn't solve my issue. I was working on a grid-based drag and drop feature that allows dragging bet ...

What is the best way to retrieve an object within a class?

Exploring a Class Structure: export class LayerEditor { public layerManager: LayerManager; public commandManager: CommandManager; public tools: EditorTools; constructor() { this.commandManager = new CommandManager(); this.lay ...

Chrome fails the karma tests while phantomjs passes them

I've been struggling with this issue for some time now and can't seem to find a solution. I'm working on an Ionic 2 project that utilizes Angular 2's testing environment. When I run 'ng test' using Karma's Chrome launcher ...

Tips for avoiding Union types in TypeScript from anticipating unnecessary keys?

My function getRespectiveConfig() returns a Union type that includes all the necessary types: interface AlphaConfig { title: string; } interface BetaConfig { id: string; } export interface EncompassingConfig { alphaConfig?: AlphaConfig; b ...

Tips for combining values with Reactive Forms

Is there a way to merge two values into a single label using Reactive Forms without utilizing ngModel binding? <label id="identificationCode" name="identificationCode" formControlName="lb ...

What is the best way to preserve the state of a component in Angular?

I need to find a way to preserve the state of a data table within my Angular 7 & Typescript application. It's essentially like saving the state of a browser tab. When I navigate to another component and return to the one with the data table, how ...

Ways to sign up for the activeDate variable in MatCalendar so you can display the month and year labels of the current active date in the

As a newcomer to Angular, I am working on creating a datepicker with a customized header. I have successfully passed a custom header for the mat-calendar component. Reference: https://material.angular.io/components/datepicker/overview#customizing-the-calen ...

What is the recommended way to retrieve the Nuxt `$config` within Vuex state? Can it only be accessed through store action methods?

After using the dotenv library for my .env file, I had to change the runtimeConfig in order to secure my project's secret key. In my most recent project, I utilized nuxt version "^2.14" in SPA mode, so I only utilized "publicRuntimeConfig" in my nuxt ...

What other methods are available to verify null and assign a value?

Is there a more efficient approach for accomplishing this task? theTitle = responsesToUse[i]["Title"]; if(theTitle == null) theTitle = ""; ...

Creating a Typescript function that can be optional when passed as a prop

I'm attempting to pass a function via props, but I want it to be optional. However, when I attempt to specify it as optional in the props interface by adding a "?" in front of the function, I encounter this error: 'propsFunction', which doe ...

Fulfill the promise once all map requests have been completed

Currently, my focus is on developing a bookmark page that retrieves bookmark results with the respective restaurant IDs. Once the response is mapped, I populate an array with objects. My objective is to ultimately resolve the entire array in order to mani ...

Varieties of data classifications for the information obtained from supabase

1 I'm encountering an issue while attempting to define the data types from Supabase. I received an error message stating: "type '{ id: string; title: string; capacity: number | null; start_date: Date | null; start_time: string | null; end_ ...

The functionality of the Angular directive ngIf is not meeting the desired outcome

We are currently working on transferring data from one component to another using the approach outlined below. We want to display an error message when there is no data available. <div *ngIf="showGlobalError"> <h6>The reporting project d ...

Creating asynchronous JavaScript constructors using a static method called "create" presents challenges when dealing with TypeScript types

I've been diving into the world of asynchronous constructors and have successfully implemented them in JavaScript. However, I'm facing a challenge with TypeScript types. Here's how it should ideally work: const a: AnyClass = await AnyClass. ...

To handle async actions in Typescript with React and Redux, ensure that all actions passed to axios are plain objects. If you need to perform

Looking for assistance with Typescript, React, and Redux. export function fetchAllMeals (subject: string){ axios .get(`https://www.themealdb.com/api/json/v1/1/search.php?s=${subject}`) .then((response: any) => { console.log(response.data) ...

Serving sourcemaps for a web extension in Firefox: A step-by-step guide

Currently in the process of developing a web extension using TypeScript, I have encountered an issue with sourcemaps not loading properly. The use of parcel to bundle my extension has made the bundling process simple and straightforward. However, while the ...

Bidirectional data binding in model-driven forms

Currently, I am working on a reactive form that includes fields for first name, last name, and display name. The goal is for the display name to automatically populate with the concatenated values of the first and last name. However, as I am still learning ...

Converting an array into an object by using a shared property in each element of the array as the key

I have an item that looks like this: const obj = [ { link: "/home", title: "Home1" }, { link: "/about", title: "About2" }, { link: "/contact", title: "Contact1" } ] as const and I want to p ...

Switch on ngbAccordion via TypeScript File

I need to implement a function in my component.ts file that will toggle the accordion using a button. Can you help me with the script for this? This is my HTML code: <button (click)="toggleAcc()" type="button" class="btn btn-pr ...