1

i have recently picked up Typescript because it seemed interesting. I have used generics in C# before and managed to do quiet a few things with generics in Typescript but now im stumped for the following use case:

I have a generic function that takes in any number of Rest arguments. These arguments are than passed to a callback function which is also provided. But i cannot seem to figure out how to make the typescript compiler accept the types i provide to implicitly be passed into the callback function.

async SampleFunction(
    cb: () => void,
    ...args: any[]
)

with this as sample usage:

let stringVariable = "lorem";
let numberVariable = 8;

SampleFunction(
    (stringArg, numberArg) => {},
    stringVariable,
    numberVariable,
)

This example results in arguments that think they are implicitly type 'any'.

my question hereby is: how can i make this function definition so that i could pass in any aditional arguments which then get their type passed into the callback function as they are passed in the same order.

2 Answers 2

5

Thanks to the help of @Etheryte i got onto the right search track.

I found the sollution i wanted which is:

function SampleFunction<T extends any[]>(
    cb: (...args: T) => void,
    ...args: T
): void {}

let stringVariable = 'lorem';
let numberVariable = 8;

SampleFunction(
    (a, b) => {}, 
    stringVariable, 
    numberVariable
);

This implicitly passes the right argument types from the function into the callback

Sign up to request clarification or add additional context in comments.

Comments

1

You can use the Parameters<T> utility type. The (...args: any[]) => any type in the extends allows any function to be passed as the callback regardless of its signature, and infers the rest from the passed function.

function sampleFunction<T extends (...args: any[]) => any>(
  callback: T,
  ...args: Parameters<T>
) {}

sampleFunction((a: string, b: number) => null, "foo"); // Doesn't pass
sampleFunction((a: string, b: number) => null, "foo", "bar"); // Doesn't pass
sampleFunction((a: string, b: number) => null, "foo", 42); // Passes
sampleFunction((a: string, b: number) => null, 42, "bar"); // Doesn't pass

1 Comment

This answer helps a lot but i only have a slight problem with it. A missmatch in argument length is getting properly reported but the implicit argument types is still any. i would love to have them be the type of the arguments implicitly.

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.