Triangle exercise with unexpected result

Can someone explain to me what’s going on in triangle? I don’t understand how the numbers decrement and then increment. I expected it to stop at <END.

"strict";

const triangle = (length) =>
  length === 0 ? "<END" : length + triangle(length - 1) + "\n" + line(length, "*");

const line = (length, character) =>
  length === 0 ? "" : character + line(length - 1, character);

console.log(triangle(10));

Result from Firefox Scratchpad:

10987654321<END
*
**
***
****
*****
******
*******
********
*********
**********

@chef4121 Welcome to the forum

In this line :fu: you return a number. You must delete length, which is a number.

const triangle = (length) => length === 0 ? "&lt;END" :  triangle(length - 1) + "\n" + line(length, "*");
const line = (length, character) => length === 0 ? "" : character + line(length - 1, character);
console.log(triangle(10));

I’m not 100%, but I think that line() is building as intended. But I don’t think triangle() is working step-wise with line(). It’s not returning:
...
8\n********
9\n*********
10\n**********
Rather it seems like the results of line got ‘stuck under’ one string that was returned by triangle. Every time triangle ran it returned \n + line(...), hence line stacked. While the first triangle to run returned one string ‘10987654321<END’.