2

I have a function that should take a function and return the 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 way to infer function/argument types from arguments?

1 Answer 1

2

You can achieve your goal by providing the arguments to your callback either as a single array value, or serially using spread syntax.

You can decide which syntax fits your preference, but here's an observation: by using the array syntax, the compiler treats the args as a tuple and preserves label information, but doesn't seem to do so using spread syntax (tested in TS v4.5.2). Perhaps this will change in a future release, as the label information is great for 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');
Sign up to request clarification or add additional context in comments.

7 Comments

@captain-yossarian I'm pretty sure it's generics with function expression syntax during variable assignment that breaks the syntax highlighter, but lang-ts is canonical: stackoverflow.com/editing-help#syntax-highlighting
you are right, because highlighting still does not work. Sorry for confusing you with this edit. Good answer!
my concern is any[] as it erases the type information for the fn. is that possible to have a generic that would preserve types? as I want to have a strict types checking
Nothing's being lost due to any existing types: there just isn't an explicit return type (which would be (...a: A) => ReturnType<F>). I'll update the answer to include one, and I'll refactor the parameters using an additional generic (which you can then reuse) to increase readability.
@deeptowncitizen Updated. Does that now answer your question satisfactorily?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.