Can the types of function parameters be extracted from an object and converted into tuples?

Consider a scenario where you have an object with functions

{
 fnNumber: (x: number) => x,
 fnString: (x: string) => x
}

and you want to transform it into a type like this

{ 
  fnNumber: number,
  fnString: string
}

This transformation can be achieved using the following code snippet

type FnParam<T> = {[key in keyof T ]: T[key]}
type FnObject<T> = {[key in keyof T]: (x: T[key]) => any}

export function create<T>(x: FnObject<T>): FnParam<T> {
 return {} as any
}

const types = create({
 fnNumber: (x: number) => x,
 fnString: (x: string) => x
})
types: : {fnNumber: number, fnString: string}

However, if the functions have more than one parameter

{
 fnNumber: (x: number, y: string) => x,
 fnString: (x: string) => x
}

You would need to represent them as tuples like this

{ 
  fnNumber: [number, string],
  fnString: [string]
}

To handle this case, you can use the following approach

type FnParam2<T> = {[key in keyof T ]: T[key]}
type FnObject2<T> = {[key in keyof T]: (...x: T[key]) => any}

export function create2<T>(x: FnObject2<T>): FnParam2<T> {
 return {} as any
}

However, TypeScript may struggle to infer tuple types from ...x: T[key]

Is there a way to resolve this issue?

Answer №1

Just a quick point to mention, in your single parameter version, you can use just T instead of FnParams. The outcome remains the same:

export function generate<T>(x: ObjFunction<T>): T {
 return {} as any
}

const types = generate({
 fnNumber: (x: number) => x,
 fnString: (x: string) => x
})
// types: : {fnNumber: number, fnString: string}

For multiple parameters, conditional types are necessary to extract the parameters, which is only possible in Typescript 3.0 or later, following the introduction of Tuples in rest parameters and spread expressions.

type ParamTypes<T> = T extends (...a: infer A) => void ? A : never 
type FuncParam<T> = { [key in keyof T]: ParamTypes<T[key]> }
type ObjFunction<T> = Record<string, (...a: any[]) => any>

export function generate<T extends ObjFunction<any>>(x: T): FuncParam<T> {
    return {} as any
}

const types = generate({
    fnNumber: (x: number, y: string) => x,
    fnString: (x: string) => x
})

types.fnNumber // [number, string]
types.fnString // [string]

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

Discovering the highest value within an array of objects

I have a collection of peaks in the following format: peaks = 0: {intervalId: 7, time: 1520290800000, value: 54.95125000000001} 1: {intervalId: 7, time: 1520377200000, value: 49.01083333333333} and so on. I am looking to determine the peak with the hig ...

Currently trapped within the confines of a Next.js 13 application directory, grappling with the implementation of a

I need to figure out how to export a variable from one component to layout.tsx in such a way that it is not exported as a function, which is currently causing the conditional check in the class name to always be true. Below is the code snippet: // File w ...

retrieving information from a JSON document

Within my application, I am utilizing a child process to run a script which then produces a result in stdout. I am currently using res.json(stdout) to transmit this output to the variable data in app.component. My goal is to extract specific data from th ...

After installing Angular Material, receiving an error stating "Module '@angular/platform-browser/animations' not found."

Every time I launch my application, an error pops up: The module '@angular/platform-browser/animations' cannot be found. Here is the content of my package.json file: { "name": "oscar-app-ihm", "version": " ...

Generate a distinct variable name within the *ngFor loop

I am trying to create a dynamic table where clicking a button displays the row directly beneath it. I checked out a helpful post on this topic, but didn't find the exact solution I needed. The current setup works but reveals all hidden rows because ...

Difficulty displaying SVGs in VueJS when using Typescript

I'm facing a strange issue that seems like it should be easy to solve. When using Vue with JavaScript as CDN, everything works perfectly (just like it does in Angular or any other framework). <img src="/assets/images/icons/myicoin.svg> However ...

Deleting specific URLs in Markdown using TypeScript

Currently, I am working with Typescript and Node v8, aiming to process markdown text and eliminate all image URLs that match specific criteria: URLs containing the term "forbidden" URLs with IP addresses I have been using the following regular expression ...

What is the best way to create an array of unspecified classes that adhere to a particular interface in TypeScript?

Currently, I am working on an interface that has specific properties and function specifications which are implemented by several classes. My objective is to create an array of arrays that contain instances of these classes. However, when I try the followi ...

Inversify: class-based contextual dependency injection

I am currently experimenting with injecting loggers into various classes using inversify. My goal is to pass the target class name to the logger for categorization. The challenge I'm facing is the inability to access the target name from where I am c ...

A TypeScript type that exclusively permits keys from an object

Is it possible to create a type in React that only accepts keys from an object mapping strings to components? export const icons: { readonly [key: string]: React.VFC } = Object.freeze({}) type IconProps = { name: // every key of `icons` } export const ...

Highcharts - Customize Pie Chart Colors for Every Slice

I'm working on an angular app that includes highcharts. Specifically, I am dealing with a pie chart where each slice needs to be colored based on a predefined list of colors. The challenge is that the pie chart is limited to 10 slices, and I need to a ...

What was the reason for the failure of the setState function in this particular instance within NextJS?

Greetings everyone! I'm encountering an issue - the setState function is not functioning in my NextJS + TS application. I attempted using state with ReactHooks, switched the component to classes, but to no avail. Interestingly, when I tested ...

Differences Between ES5 and ES6 in Dealing with Arrays in JavaScript

I need assistance with converting the code snippet below as I suspect it is related to an ES5/ES6 compatibility issue. Any help would be highly appreciated. this.rows = Array.from(Array(Math.ceil(this.subCategoryModels.length / 3)).keys()); Upon attempti ...

What's the best way to determine the event type when a mouseDown occurs in React while working on a canvas?

I've been tackling the challenge of incorporating the <canvas /> element into a react project, but I'm encountering difficulties with determining the appropriate event type for it. In my quest for answers, I stumbled upon this insightful ar ...

The DatePicker in Angular2 and Typescript is unable to execute the property 'toggle' because it is undefined

I've encountered an issue with the calendar icon for angular2's datepicker. Whenever I try to click on it, I keep getting this error: TypeError: Cannot read property 'toggle' of undefined at Object.eval [as handleEvent] (Admiss ...

Issue: Using the command 'typings search' successfully locates a package, however, when attempting to install it using 'typings install', the process fails

I am currently attempting to install the Google Auth2 typings using 'typings': > typings search gapi.auth2 This command returns: NAME SOURCE HOMEPAGE DESCRIPTION VERSIONS UPDATED gapi.auth2 d ...

The functionality of new Date() is inconsistent when encountering a daylight savings time switch

In my current situation, I am facing an issue when passing "year, month, date, time" to the Date() function in order to retrieve the datetime type. Utilizing Google Chrome as the browser. The Windows system is set to the EST timezone (-05:00). Daylight S ...

Despite strongly typed manipulations, the type of a Typescript variable remains unchanged

Enhanced TS Playground Example Script type Base = { name: string } type ExtA = { address: string } type ExtB = { streetName: string; } function handler<T extends Base>(input: T): T {return input} /** how can I create a composite object? */ ...

TSX is throwing an error: "No matching overload found for this call."

Just starting out with React and TypeScript here! I tried passing the propTypes into a styled-component and ran into this error message: Oh no, there's an issue with the overloads. Overload 1 of 2 seems to be missing some properties. Overload 2 of ...

An error in TypeScript has occurred, stating that the type 'IterableIterator<any>' is neither an array type nor a string type

Hey there! I'm currently working on an Angular project and encountering an error in my VS Code. I'm a bit stuck on how to fix it. Type 'IterableIterator<any>' is not an array type or a string type. Use compiler option '- ...