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

Tips for maintaining license comments in TypeScript 2.5

When creating JavaScript libraries using TypeScript v2.5 and tsc, it is important to include license comments in the built files. However, the removeComments configuration in the tsconfig.json file can remove certain comments, including license comments. ...

Avoid triggering the API with rapid successive clicks

My project involves creating an Instagram-clone with like and dislike buttons. When a user is logged in and hasn't liked or disliked a post yet, both buttons appear as black. If the user likes a post, the like button turns blue, and if they click disl ...

Nextjs API call ended without a response being sent

I am currently facing a challenge in my NextJS project as my endpoint API does not support multiple calls, and I am looking to implement a data refresh every 3 minutes from the original source. To achieve this, I have integrated an API in NextJS by creati ...

The Standalone Component does not appear for debugging in webpack:source when utilizing an incompatible version of Node

I have developed two components: However, after running ng serve, I am only able to see one component in the source of the Chrome browser: How can I troubleshoot this standalone component? My breakpoints are not being hit in VS Code with the following co ...

NodeJs is facing a challenge with the global variable for retrieving all routes methods after successful sign in

I have created a blog page with options for signing up and signing in. I used the req.locals.<name> method Using the GET method. Code snippet from server.js app.get('*',(req,res, next) => { res.locals.user = req.user || null; ...

Access to this page via the Odesk API in node.js is restricted and unauthorized

/** * Here is an example of how to use the oDeskAPI * * @package oDeskAPI * @since 09/22/2014 * @copyright Copyright 2014(c) oDesk.com * @author Maksym Novozhylov <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data ...

Generating a .png image using the data received from the client [node]

I need to create a highchart client-side and save a PNG of that chart server-side. After successfully generating the highchart and converting it to a PNG using the following function: function saveThumbnail(graph_name, chart) { canvg(document.getEleme ...

Leveraging Vue's "v-slot" functionality to create a specified slot within a JavaScript object

I have turned to this platform seeking guidance on using "v-slot" while utilizing a syntax that involves a javascript object. This specific method was introduced in the online course Intro to Vue3 which I recently completed. Below is an image de ...

I'm having trouble inputting text into my applications using React.js and TypeScript

I am encountering an issue where I am unable to enter text in the input fields even though my code seems correct. Can anyone help me figure out what might be causing this problem? Below is the code snippet that I am referring to: const Login: SFC<LoginP ...

Storing knockout view model data in a database and fetching it back

I am currently working on a web form that utilizes knockout, and I need to add a new feature that allows users to save the form as a draft in the database. Later on, they should be able to load it again to make modifications or submit it. Is there a built ...

Retrieve functions contained within the component.ts file of an Angular library: tips and tricks

I have developed an Angular library, named 'mylib', where I have utilized only the mylib.component.ts file. The HTML element codes are included inside the template variable of this file, along with the functions responsible for modifying these el ...

I'm attempting to insert a line break after HTML elements that are being added from JavaScript code inside a `display: flex` div

I'm facing an issue where line breaks are not added after HTML elements are inserted via JavaScript upon clicking a button. For instance, the data from the inputs doesn't get separated even when I click submit multiple times: To illustrate, her ...

Encounter a Typescript error when dealing with "app.ws" while using express-ws

I have a small project in mind where I want to create a BabyCam that can be accessed from any web browser using a Raspberry Pi Zero. My plan is to set up a web socket using express-is to stream video to multiple clients. I'm utilizing the raspivid-str ...

Dealing with the Back Button Problem in History API and History.js

Using Ajax to load the page presents a challenge when the user clicks the back button. Here is the scenario: Initial page (index.php) is loaded User clicks on a link The new page loads successfully via Ajax User clicks the back button The initial page is ...

I'm puzzled by this C++ array declaration

When you declare an array in C++ like this: int myArray[8] = {0,}; What is the significance of this syntax? ...

Simulated FileList for Angular 5 App Unit Testing

Imitation FileList In my pursuit of writing a unit test (Angular5), I have encountered the need for a FileList. Despite researching extensively, I have been unable to uncover any clues or solutions. I am starting to question whether this is even feasible ...

Is there a way to generate and transmit a text file using XmlHttpRequest or $.ajax?

The server is anticipating an html or txt file to be sent from a form named "websitetopdf". The file is dynamically created on client javascript and should only function properly on Chrome. Below is the form that needs to be used for sending: <form ac ...

Modify an element on one webpage using a function called from another webpage

I am currently working on a website design that involves displaying images on various frames. While I have managed to change content across different frames, I am now exploring the possibility of changing content across different web pages. Here is the se ...

Locate all nodes in neo4j that are connected to nodes matching a specified list of property values of a certain length

To clarify, I am interested in achieving the following (preferably using node/JS): Imagine you have a set of 3 job requirements ('JavaScript', 'PHP', 'MySQL'). In my graph setup, each Person node can be linked to multiple Sk ...

Are you searching for ways to convert an object into an array?

I have a dynamically built object and I need to extract specific fields (the dynamic ones) from it and convert them into an array. In the following code snippet, my goal is to convert towers[X] into an array of objects. {id: "", description: "Teste", tow ...