Obtain the parameters of a function within another function that includes a dynamic generic

I am attempting to extract a specific parameter from the second parameter of a function, which is an object. From this object, I want to access the "onSuccess" function (which is optional but needed when requested), and then retrieve the first dynamic parameter of that function.

Although

Parameters<NonNullable<Parameters<typeof sampleFunction>[1]["onSuccess"]>>[0]
does work, I prefer not to use it everywhere as it can be quite difficult to read. I would like to create a more dynamic approach like:
ResponseOf<typeof sampleFunction>

TS playground link

interface ApiCallback<T = any> {
  onSuccess?: (response: T, headers?: any) => void;
  onFailure?: (error: unknown) => void;
  label: string;
  // ...other
}

interface ApiActionPayload<T = any> extends ApiCallback<T> {
  url: string;
  // ... other
}

interface ApiAction<T = any> {
  type: "API";
  payload: ApiActionPayload<T>;
}

function apiAction<T = any>({
  url = "",
  label = "",
  ...props
}: ApiActionPayload<T>): ApiAction<T> {
  return {
    type: "API",
    payload: {
      url,
      label,
      ...props
    }
  }
}

const sampleFunction = (_param1: any, callbacks: ApiCallback<{ data: any[] }>): ApiAction => {
  return apiAction({
    url: "google.com",
    ...callbacks
  })
}

type DesiredNonDynamicType = Parameters<NonNullable<Parameters<typeof sampleFunction>[1]["onSuccess"]>>[0];


export type ResponseOf<
  T extends (
    first: any,
    second: { onSuccess?: (x: any) => any; label: string;[k: string]: any },
    ...args: any[]
  ) => any> = T extends (first: any, second: { onSuccess?: (x: infer U) => any;[k: string]: any }, ...args: any[]) => any
  ? U : never;


type DesiredType = ResponseOf<typeof sampleFunction>;

One solution I have experimented with is:

export type ResponseOf<
  T extends (
    first: any,
    second: { onSuccess?: (x: any) => any; label: string; [k: string]: any },
    ...args: any[]
  ) => any
= T extends (first: any, second: { onSuccess?: (x: infer U) => any; [k: string]: any }, ...args: any[]) => any
  ? U
  : never;

Answer №1

To simplify this process, you can utilize the ApiCallback utility type within your conditional type inference. Instead of attempting to reverse-engineer, using ApiCallback<infer U> directly is much more efficient. Here's an example:

export type ResponseOf<T> =
  T extends (first: any, second: ApiCallback<infer U>, ...args: any) => any ? U : never

This approach will give you the desired behavior:

type DesiredType = ResponseOf<typeof sampleFunction>;
/* type DesiredType = {
    data: any[];
} */

Access the Playground link to view the code.

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

Apologies, the module "@org-name/package-name" could not be located

I've hit a roadblock for the past few days. My goal is to create a new npm package that wraps an API I've been developing. When bundling the package, everything seems to be fine in the /dist folder. However, when attempting to test it in a front ...

What is the most effective method for delivering a Promise after an asynchronous request?

Currently, I am working on creating an asynchronous function in TypeScript that utilizes axios to make an HTTP request and then returns a Promise for the requested data. export async function loadSingleArweaveAbstraction(absId : string) : Promise<Abstra ...

Dealing with Undefined TypeScript Variables within an array.forEach() loop

Could someone help me understand my issue? I have an array of a specific object, and I am trying to create a new array with just the values from a particular field in each object. I attempted to use the forEach() method on the array, but I keep encounteri ...

Angular displays X items in each row and column

I've been struggling with this task for the past 2 hours. My goal is to display a set of buttons on the screen, but I'm facing some challenges. The current layout of the buttons doesn't look quite right as they appear cluttered and unevenly ...

Is there a way to retrieve the name of a document stored within a collection using Firebase Firestore and Firebase Storage

When fetching data from the 'users' collection in Firebase Firestore and mapping the response, I have a function that converts the array of domains and filters out any domains that do not meet certain criteria. Here's an example: Sample dom ...

Generate detailed documentation for the functional tests conducted by Intern 4 with automated tools

I need to automatically generate documentation for my Intern 4 functional tests. I attempted using typedoc, which worked well when parsing my object page functions. However, it failed when working with functional test suites like the one below: /** * Thi ...

Strategies for displaying error messages in case of zero search results

I am currently developing a note-taking application and facing an issue with displaying error messages. The error message is being shown even when there are no search results, which is not the intended behavior. Can someone help me identify what I am doing ...

Angular 8's array verification feature lacks the ability to recognize preexisting elements

I've been trying to add and delete items in an array when a user selects or deselects the same item. However, it appears that either my array is not working properly or there is a bug in my code causing it to fail. <div class="grp-input"> ...

Struggling to locate components in your React, Next.JS, and Typescript project? Storybook is having trouble finding them

I have set up Storybook with my Next.js, TypeScript, and React project. The main project renders fine, but Storybook is breaking and giving me the error message: "Module not found: Error: Can't resolve 'components/atoms' in...". It appears t ...

The inner map function isn't being executed in Rxjs

I have written some code that utilizes two pipes to load a product instance along with its playlist. In case there is an error while loading the playlist, the property is set to null: getProduct(productId: number): Observable<ProductDTO> { retur ...

Operating on Javascript Objects with Randomized Keys

Once I retrieve my data from firebase, the result is an object containing multiple child objects. myObj = { "J251525" : { "email" : "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6c3823212 ...

Using React MUI Select in combination with react-hook-form does not seem to be compatible with Cypress testing

Within my React application, I have implemented a form that includes a dropdown select. Depending on the option selected from the dropdown, different input fields are rendered. const [templateType, setTemplateType] = useState(""); const { regi ...

Contrast between categories and namespaces in TypeScript

Can you clarify the distinction between classes and namespaces in TypeScript? I understand that creating a class with static methods allows for accessing them without instantiating the class, which seems to align with the purpose of namespaces. I am aware ...

Ways to receive one of two variations

Dealing with different cases for type is my current challenge. In a React Functional Component, I have a callback function property that accepts an argument of either string or number. interface InputProps { getValue?: (value: string | number) => vo ...

The InMemoryCache feature of Apollo quietly discards data associated with fragments that are declared on the main

After sending the following query to my GraphQL server: fragment B on root_query { foo { id } } query A { ...B } The data received from the server includes the foo field. However, when I retrieve it using Apollo's InMemoryCache a ...

Using a function to implement *ngFor results in generating a loop

When using *ngFor in Angular with a function that returns data, the function gets called multiple times and can sometimes result in a loop: app.component.ts export class AppComponent { getArray(): string[] { //I can track when this function is c ...

Gulp is failing to create a JavaScript file from TypeScript

Below is the Gulp task I am using: var gulp = require('gulp'); var typescript = require('gulp-typescript'); var sourcemaps = require('gulp-sourcemaps'); var tsProject = typescript.createProject('tsconfig.json'); var ...

Angular 7: The Pitfalls of Incorrect URL Concatenation

After navigating to a different page within my project, an unexpected 404 error with the wrong URL appears in the console. Here's what it looks like: https://localhost:4420/example.com/api/customers However, it should actually look like this: h ...

Steps to fix: "Rule '@typescript-eslint/consistent-type-assertions' is missing a definition"

My React app is failing to compile because it can't find the rule definition for '@typescript-eslint/consistent-type-assertions'. I'm feeling quite lost at the moment. I can't seem to locate any current rule definitions within the ...

Dealing with the "this" problem in TypeScript and its impact on scope

Here is my code snippet: class MyClass { name = "MyClass"; // traditional method definition getName1(){ return this.name; } // method defined as an arrow function getName2 = () => { return this.name; ...