Why does recursive/nested `setTimeout` does not stop execution without an `else` statement?

I am learning to use recursive setTimeout function.

My task is to create a function that takes 2 number arguments, from and to and prints each number in between to the console, one at the time with the delay of 1 second in between.

My question is, why function printNumbers1 does not stop execution after printing number 4 to the console? The assumption is that the timerID is incorrect, but I do not understand why.

const DELAY = 1000;

const printNumbers1 = (from, to) => {
  let counter = from;
  let timerID = setTimeout(function run() {
    console.log(counter);
    counter++;

    if (counter > to) clearTimeout(timerID);

    // the function not stop the invocation without the `else` statement
    timerID = setTimeout(run, DELAY);
  }, DELAY)
}

const printNumbers2 = (from, to) => {
  let counter = from;
  let timerID = setTimeout(function run() {
    console.log(counter);
    counter++;
    if (counter > to) clearTimeout(timerID);
    else {
      timerID = setTimeout(run, DELAY);
    }
  }, DELAY)
}

printNumbers1(1, 4); // continues to execute after 4th invocation
printNumbers2(1, 4); // stops execution after 4th invocation