Describing a function in Typescript that takes an array of functions as input, and outputs an array containing the return types of each function

Can the code snippet below be accurately typed?

function determineElementTypes(...array: Array<(() => string) | (() => number) | (() => {prop: string}) | (() => number[])>) {
   /// .. do something
   /// .. and then return an array with each functions result
   return array.map(arg => arg())
}

const [varA, varB, varC] = determineElementTypes( () => "", () => ({prop: "prop"}), () => [1,2,3] )
// how can this be typed appropriately so that the : 
// varA: string
// varB: {prop: string}
// varC: number[]

Answer №1

Successfully achieved the task using

type ReturnValues<T extends Array<(...a: any[]) => any>> = {
  [P in keyof T]: T[P] extends (...a: any[]) => infer R ? R : never
}

type CustomArrayTypes = (() => string) | (() => number) | (() => {prop: string}) | (() => number[])

function arrayElementValues<T extends CustomArrayTypes[]>(...array: T): ReturnValues<typeof array> {
   return array.map(arg => arg())
}

const [resultA, resultB, resultC] = arrayElementValues( () => "", () => ({prop: "prop"}), () => [1,2,3] )

Big thanks to everyone for their assistance!!

Answer №2

I have doubts about the accuracy of typing this correctly. It seems like you are dealing with a tuple rather than an array, as the functions in question have different signatures and the return type of arrayElementTypes should match each function's return type in the tuple.

However, I don't want to rule out the possibility completely, as I've seen some remarkable solutions achieved through the use of generics and conditional types before.


Edit: I have devised some foundational types that could assist in finding the solution, but it will require some assembly on your end :)

// defining any function
type Fn = () => unknown;

// representing a tuple/array of functions
type FnArr = readonly Fn[];

// extracting the first function in the tuple
type Head<T extends FnArr> = T extends [infer HeadFn, ...any[]] ? HeadFn : never;

// obtaining the remaining functions in the tuple
type Tail<T extends FnArr> = T extends [any, ...infer TailFns] ? TailFns : never;

Using these basic building blocks, you can derive the return types of each function within your tuple. While this doesn't offer a direct solution, leveraging recursively defined conditional types could potentially lead you to one :)

const [varA, varB, varC] = arrayElementTypes( () => "", () => ({prop: "prop"}), () => [1,2,3] )
// how can this be typed appropriately so that the : 
// varA: string
// varB: {prop: string}
// varC: number[]

type ExampleFns = [ () => string, () => {prop: "prop"}, () => number[] ];

type TypeForVarA = ReturnType<Head<ExampleFns>>;                // F1 = string
type TypeForVarB = ReturnType<Head<Tail<ExampleFns>>>;          // F2 = {prop: "prop"}
type TypeForVarC = ReturnType<Head<Tail<Tail<ExampleFns>>>>;    // F3 = number[]

Answer №3

const [valueA, valueB, valueC, valueD]: Array<string | number | {prop: string} | number[]> = arrayElementTypes( () => "", () => ({prop: "prop"}), () => [1,2,3] )

Is this in line with what you are looking for?

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

D3.js Issue: The <g> element's transform attribute is expecting a number, but instead received "translate(NaN,NaN)"

I encountered an error message in my console while attempting to create a data visualization using d3. The specific error is as follows: Error: <g> attribute transform: Expected number, "translate(NaN,NaN)". To build this visualization, I ...

Is it necessary to include async/await in a method if there is already an await keyword where it is invoked?

Here are the two methods I have written in Typescript: async getCertURL(pol: string): Promise<string> { return await Api.getData(this.apiUrl + pol + this.certEndpoint, {timeout: 60000}).then( (response) => { return response.data.certUR ...

Error message displaying 'class-transformer returning undefined'

I'm new to working with the class-transformer library. I have a simple Product class and JSON string set up to load a Product object. However, I'm encountering an issue where even though I can see the output indicating that the transformation was ...

The NextJS API is throwing an error due to a mysterious column being referenced in

I am currently in the process of developing an API that is designed to extract data from a MySQL table based on a specific category. The code snippet below represents my current implementation: import { sql_query } from "../../../lib/db" export ...

Looking to retrieve the raw HTTP header string in Node.js using express.js?

Currently, I am utilizing Node.js and express.js for my work. The project I am currently working on requires me to access the raw strings of the HTTP headers (charset and accepted). In express.js, there is a function available that can provide the charset ...

"Error: imports are undefined" in the template for HTML5 boilerplate

After setting up an HTML5 Boilerplate project in WebStorm, I navigate to the localhost:8080/myproject/src URL to run it. Within the src folder, there is a js directory structured like this: libraries models place.model.ts place.model.js addr ...

Angular 5 Image Upload - Transfer your images with ease

I am having trouble saving a simple post in firebase, especially with the image included. This is my current service implementation: uploadAndSave(item: any) { let post = { $key: item.key, title: item.title, description: item.description, url: '&a ...

My component is displaying a warning message that advises to provide a unique "key" prop for each child in a list during rendering

I need help resolving a warning in my react app: Warning: Each child in a list should have a unique "key" prop. Check the render method of `SettingRadioButtonGroup`. See https://reactjs.org/link/warning-keys for more information. at div ...

Failed validation for Angular file upload

I attempted to create a file validator in the front end using Angular. The validator is quite straightforward. I added a function onFileChange(event) to the file input form to extract properties from the uploaded file. I then implemented a filter - only al ...

When using res.json(), the data is returned as res.data. However, trying to access the _id property within it will result

I'm facing a challenge in comprehending why when I make a res.json call in my application, it successfully sends data (an order object). However, when I attempt to access and assign a specific piece of that data (res.data._id) into a variable, it retu ...

Trying to assign a property to an undefined variable inside a function

At the moment, I am configuring error messages on a login page for an extension using vue, and encountering issues within the importCreds() function. data(){ return { url:'', apikey:'', error:'', } }, meth ...

How to Enhance GraphQL Mutation OutputFields with a Function Generator

I'm encountering issues while trying to incorporate a function generator within a GraphQL mutation. The function generator is utilized to streamline the promise chain inside the mutation. Prior to refactoring the code, everything was functioning corr ...

`Datatables sorting feature for British date and time`

I'm currently attempting to organize a column in a table using the DataTables plugin that contains UK date and time formats such as: 21/09/2013 11:15 Implementing Ronan Guilloux's code: jQuery.extend( jQuery.fn.dataTableExt.oSort, { "uk_dat ...

Execute supplementary build scripts during the angular build process

I've developed an Angular application that loads an iframe containing a basic html page (iframe.html) and a Vanilla JavaScript file (iframe.js). To facilitate this, I've placed these 2 files in the assets folder so that they are automatically cop ...

Issues arise when upgrading from Angular 8 to 9, which can be attributed to IVY

After successfully upgrading my Angular 8 application to Angular 9, I encountered an error upon running the application. { "extends": "./tsconfig.json", "compilerOptions": { "outDir": ". ...

What is the most efficient method to import multiple MaterialUI components using a shared namespace without requiring the entire library to be imported

In order to prevent name mixing with other libraries, I want my MaterialUI components to be under the same namespace. For example, ensuring that <Box> references <MaterialUI.Box> and not <SomeOtherLibrary.Box>. Although it seems like a si ...

Unleashing the full potential of Azure DevOps custom Tasks in VS Code and TypeScript: A guide to configuring input variables

Scenario: I have developed a custom build task for Azure DevOps. This task requires an input parameter, param1 The task is created using VS Code (v1.30.1) and TypeScript (tsc --version state: v3.2.2) Issue During debugging of the task, I am unable to pr ...

Node.js used to create animated gif with unique background image

As I navigate my way through the world of node.js and tools like express and canvas, I acknowledge that there might be errors in my code and it may take me some time to grasp certain concepts or solutions. My current project involves customizing a variati ...

Angular generates a dynamic interface to fetch data from Wordpress REST API posts (special characters in property names are causing issues)

I've been developing a front-end Angular application that interacts with the Wordpress REST API to fetch and display post data. My goal is to create an interface to handle the responses and render the posts in the template. However, I encountered an ...

Solving required packages in Express server

I am encountering difficulties with resolving dependencies on my express server. Below is the structure of my project: Calculator --dist ----app -------calculator.js -------server.js --node_modules --src ----app --------calculator.js --------server.js -- ...