NSjonas
NSjonas

Reputation: 12032

Typescript function that takes a function and returns a function with subset of parameters

So... this might be hard to follow but here it goes...

I want to create a function f() that accepts a function as it's parameter and returns a new function that has the same parameters excluding the first parameter (which can be concretely typed).

function f<R, A extends (s: string) => R>(func: A): () => R;  // no extra params
function f<R, T1, A extends (s: string, a1: T1) => R>(func: A): (a1: T1) => R; // 1 extra
function f<R, T1, T2, A extends (s: string, a1: T1, a2: T2) => R>(func: A): (a1: T1, a2: T2) => R; // 2 extra
function f(func: (...x: any[]) => any) {
  return (...x) => {
    return func('hello', ...x);  //call function.  'hello will always be passed as first param, followed by the rest
  };
}

In this example, f() should basically take any function where the first parameter is a string (s) and return a new function with 0 to 2 parameters (a1 & a2 if present in passed function; s will be excluded).

So if I were to pass:

function testFunc(x: string, y: number): number{
  return x.length + y;
}

const x = f(testFunc);

I would expect x to be type (a1: number) => number. However, instead I'm getting (a1: {}) => {}...

Is what I'm trying to do even possible?

Upvotes: 1

Views: 226

Answers (1)

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 221004

You have too many free type parameters and it's messing up generic inference. The function should look like this (extra overloads omitted for brevity):

function f<R>(func: (s: string) => R): () => R;
function f<R, T1>(func: (s: string, a1: T1) => R): (a1: T1) => R; // 1 extra
function f(func: (...x: any[]) => any) {
  return (...x) => {
    return func('hello', ...x);  //call function.  'hello will always be passed as first param, followed by the rest
  };
}

function testFunc(x: string, y: number): number{
  return x.length + y;
}

// x: (a1: number) => number
const x = f(testFunc);

Upvotes: 2

Related Questions