0

This works:

function test(msg:string){
   console.log(msg);
}

setTimeout(test, 1000, ["Hi!"];

...in that it will print out "Hi!" to the console after one second.

This also works:

function test(){
   console.log("Hi!");
}

function callTest(next: () => void){
   next();
}

callTest(test);

In that it also prints out "Hi!" to the console.

The following results in the error "TypeError: next is not a function". Why?

function test(){
   console.log("Hi!");
}

function callTest(next: () => void){
   next();
}

setTimeout(callTest, 1000, [test]);

It sure looks like a function to me! If the 1st code snippet works it shows that I have the form generally right to use setTimeout and send parameters to the callback, and the 2nd code snippet shows that this is the correct form to call a function passed in as a parameter - why isn't my use of setTimeout in the 3rd code snippet working?

1 Answer 1

6

You just need to pass the list of arguments directly at the end of the arguments you pass to setTimeout:

setTimeout(callTest, 1000, test);

If you had more arguments, you'd do:

setTimeout(callTest, 1000, test, a, b, c);

There's no need to put them in an array like you'd do if you were to call Function.prototype.apply. The reason you are getting an error is that the way you do it setTimeout passes an array of length one that contains a reference to the test function.

The reason your earlier example with the string works is that console.log is absolutely okay with dumping an array to the console. And there's no opportunity for TypeScript to make an issue of it because this is the definition of setTimeout when there's a list of arguments to pass to the function that will be called:

declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;

As you can see type checking is turned off by the use of any.

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

5 Comments

Ah - so you don't pass an array of parameters, you just keep listing them? Like if callTest took 2 params it would be like: setTimeout(callTest, 1000, param1, param2)? Why didn't I get a TypeError in my first example where I was passing an array as the parameter where it was expecting a string? (You are totally correct and I'll mark this as the correct answer, but I just want to totally understand it.)
The setTimeout you show in your comment is correct. Your first example had an error. In the callTest function you were calling test() directly rather than calling next().
That was just a posting error - I fixed it in the question. Your answer did it for me (just waiting for the time to pass to mark as complete). I was curious why in the first code snippet it didn't give a type error, but I guess console.log is OK with taking in an array of a single string and the function signature wouldn't have thrown a TypeError so that makes sense.
Yeah, I focused on the wrong example. I've edited my answer to address the earlier example. Let me know if the explanation needs clarification.
Makes perfect sense. I'll just say that I made this error from reading the documentation which says setTimeout(callback, delay[, ...args]), but I read it as setTimeout(callback, delay,[ ...args]). One character difference (my error) and it sent me down this rabbit hole!

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.