TypeScript Self-driving Car Challenge task: executing a sequence of turns

I’ve started to implement one of the credit tasks of the TypeScript Self-driving car project: Write code that will call .respond() many times with new events to see a sequence of turns.

I managed to do so with code like this at the bottom of in index.ts:

let count = 0;
const intervalID = setInterval(() => {
  autonomousCar.respond(getObstacleEvents());
  count++;
  if (count === 10) {
    clearInterval(intervalID);
  }
}, 1000);

With this code, the car takes new turns every second for 10 seconds, so it works. However I don’t like the fact that it’s all “loose” and defined globally. So I wanted to encapsulate this in a helper function, setTimer(), which I defined in computer-vision.ts and exported into my index.ts.

This is the exported setTimer() function:

export function setTimer(callback: () => void, seconds: number): void {
  let count = 0;
  const intervalID = setInterval(() => {
    callback();
    count++;
    if (count === seconds) {
      clearInterval(intervalID);
    }
  }, 1000);
}

And this is the call I make in index.ts:

setTimer(autonomousCar.respond(getObstacleEvents()), 10)

The problem and my question:
I immediately get a TS error on that call: Argument of type 'void' is not assignable to parameter of type '() => void'
I understand what the error means but no why it happens. At the top of the program, the respond() method is typed: respond: (events: Events) => void;. So how is it not a match with the type I annotated on the parameter of setTimer()? Why does TS only focus on the return type of respond() which is void?

As a reminder, the respond() method looks like this:

respond(events: Events) {
    if (!this.isRunning) {
      return console.log('The car is off.');
    }
    Object.keys(events).forEach((eventKey) => {
      if (!events[eventKey]) {
        return;
      }
      if (eventKey === 'ObstacleLeft') {
        this.steeringControl.turn('right');
      }
      if (eventKey === 'ObstacleRight') {
        this.steeringControl.turn('left');
      }
    });
  }

What I tried to change:

  • If I change the type annotation of the parameters of setTimer to (callback: any, seconds: number)
    → No more TS error, the program runs respond() once, but then I get a TypeError: callback is not a function

  • If I remove the parentheses and just write callback inside the function body: the program runs respond() once and stops after the number of seconds I passed in setTimer() (10 seconds in this example)

Full code is available here: https://www.codecademy.com/workspaces/62c16447551a7175e9c57f56

That TS error is really nagging me, so if anyone could help me understand it, I would be so grateful :slight_smile: