Develop the data structure according to the function signature specified in Typescript

I am trying to create a function that will take another function as input and return a new function with the same parameters list.

const fn1 = (id: string) => {};
const fn2 = (key: string; value: string) => {};

const caller = <F = ??, A = ??>(fn: F, args: { ?? A }) => {
  fn(...args);
  const recall = (...p: A) => fn(...p);
  return recall;  
}

caller(fn1, { id: '123' });
const recall = caller(fn1, { key: '1', value: '2' });
recall('1', '2');

Is there a method to automatically determine function/argument types based on the provided arguments?

Answer №1

To reach your objective, you have the option of passing arguments to your callback either in a single array value or sequentially using spread syntax.

Which syntax you prefer is up to you, but here's an interesting insight: when using the array syntax, the compiler treats the arguments as a tuple and retains label information, which doesn't seem to be the case with spread syntax (tested in TS v4.5.2). It's possible that this behavior might change in a future release, as preserving label information can greatly enhance developer experience.

TS Playground link

type Fn<
  Params extends unknown[] = any[],
  Result = any,
> = (...params: Params) => Result;

// array args
function callerArr <
  F extends Fn,
  P extends Parameters<F>,
  R extends ReturnType<F>,
>(fn: F, args: P): Fn<P, R> {
  fn(...args);
  return (...p: P) => fn(...p);
}

// spread args
function callerSpread <
  F extends Fn,
  P extends Parameters<F>,
  R extends ReturnType<F>,
>(fn: F, ...args: P): Fn<P, R> {
  fn(...args);
  return (...p: P) => fn(...p);
}

const fn1 = (id: string) => {};
const fn2 = (key: string, value: string) => {};

// array args
callerArr(fn1, ['123']);
const recallArr = callerArr(fn2, ['1', '2']);
recallArr('1', '2');

// spread args
callerSpread(fn1, '123');
const recallSpread = callerSpread(fn2, '1', '2');
recallSpread('1', '2');

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

There is a potential for the object to be 'undefined' when calling the getItem method on the window's local storage

if (window?.sessionStorage?.getItem('accessToken')?.length > 0) { this.navigateToApplication(); } Encountering the following error: Object is possibly 'undefined'.ts(2532) Any suggestions on how to resolve this issue? I am attem ...

Leverage the power of Typescript to flatten a JSON model with the help of Class

Currently, I'm exploring how to utilize the class transformer in TypeScript within a Node.js environment. You can find more information about it here: https://github.com/typestack/class-transformer My goal is to flatten a JSON structure using just on ...

How can the Calendar Ant Design showcase events that have fluctuating dates?

Seeking a solution to display events on an Ant Design Calendar using dateCellRender with dates stored in a variable object. Here's an example of the object: [ { "id": 1, "content": "Example", & ...

Create a class where each method is required to be a "getter" function

Is it feasible to establish a class in which all methods must be getters? Possible Implementation: class Example implements AllGetters { get alpha () { } get beta () { } } Not Acceptable: class Example implements AllGetters { get alpha () { ...

Issue with dynamically typed object properties in Typescript codebases

Check out this TypeScript code snippet: export type Mutation = (state: State, data: unknown) => void export type Mutations = { [key: string]: Mutation } private buildMutations(): Mutations { return { ['3']: (state, data) => ...

The error message "TypeError: Attempting to access the 'map' property of an undefined value (React JS)" was displayed

I'm currently working on a recursive function that needs to iterate over an object type called ItemType. However, I encountered an error message: TypeError: Cannot read property 'map' of undefined This is the code snippet causing the issue: ...

Why are other elements not appearing on the index.html page when <app-root> is not included?

Just started delving into Angular and following some tutorials. The project was set up using Angular CLI. Created a new component named navbar on top of the default component and wanted to check if the navbar loads in the index.html at startup. The navbar ...

How to filter specific attributes from a JSON object and transform them into an observable with RxJS

Consider the JSON data that is being received: { "events": [... ], "total": 12341, "students": [ { "id": 1, "first_name": "John", " ...

What causes different errors to occur in TypeScript even when the codes look alike?

type Convert<T> = { [P in keyof T]: T[P] extends string ? number : T[P] } function customTest<T, R extends Convert<T>>(target: T): R { return target as any } interface Foo { x: number y: (_: any) => void } const foo: Foo = c ...

Using Typescript to access keys of an interface that extends another interface

One of the interfaces I have is the Basic interface: interface Basic { [key: string]: { data: string; }; } There is another interface that extends the Basic interface: interface Another extends Basic { 'onekey': OneKeyData; 's ...

What is the best approach to perform type checking on a function that yields varying types depending on the values of its

Currently, I am facing a challenge with a function that takes an argument and returns a different type of value depending on the argument's value. For instance: function foo(arg: 'a' | 'b') { if (arg === 'a') { ret ...

The specified column `EventChart.åå` is not found within the existing database

I've been developing a dashboard application using Prisma, Next.js, and supabase. Recently, I encountered an issue when making a GET request. Prisma throws an error mentioning a column EventChart.åå, with a strange alphabet "åå" that I haven&apos ...

What is the best way to halt numerous requests in progress in Angular?

I have a function called getList() in the SearchService: public getList() { // HTTP POST call as an observable // Pipe with a few map transformations } When initializing my ListComponent, I create an Observable like this: ngOnInit(): void { ...

Changing the status of a higher-level component from within a nested component using immutable methods

I have a collection of objects with various properties. columns = [ {Header: ƒ, Cell: ƒ, sortable: false, show: true}, {Header: ƒ, accessor: "firstName", sortable: false, show: true}, {Header: ƒ, accessor: "status", so ...

Exploring the world of Node.js and sequelize-typescript - diving deep into data access entities and business

Utilizing the sequelize-typescript library in my Node.js application. I have a Category class that corresponds to a category table. import { Model, Table, Column } from "sequelize-typescript"; @Table export class Category extends Model<Category>{ ...

Encountering Flow type errors when declaring global variables in React

type Props = { checkedItems:any }; class MyApp extends Component<Props> { constructor(props) { super(props); this.checkedItems = []; } } In this code snippet, I am utilizing Flow for type checking within a React class component. However ...

What role does enum play in typescript?

What is the purpose of an enum in typescript? If it's only meant to improve code readability, could we achieve the same result using constants? enum Color { Red = 1, Green = 2, Blue = 4 }; let obj1: Color = Color.Red; obj1 = 100; // IDE does not sh ...

Incorporate a 'Select All' functionality into ion-select by adding a dedicated button

Looking for a way to set custom buttons on ion-select through interfaceOptions in ionic 4? HTML <ion-item> <ion-label>Lines</ion-label> <ion-select multiple="true" [(ngModel)]="SelectedLines" [interfaceOptions]="customAlertOption ...

What are some ways to utilize TypeScript in incorporating extensions to `koa.Request` packages?

Struggling to utilize both koa-tree-router and koa-bodyparser simultaneously, encountering persistent TypeScript errors: export const userLoggingRouter = new KoaTreeRouter<any, DefaultContext>(); userLoggingRouter.post('/logs/action', (ctx ...

Tips for accurately inputting a global object with an index

I'm in the process of converting a large monolithic JavaScript application to TypeScript and am facing an issue regarding typing a specific module. I am seeking guidance on how to approach this particular problem. It's important to note that I d ...