Можно сделать так (оставил весь ваш код, только заменил порядок одной строчки, чтобы заработало):
function sumInput() {
let arr = []
let sum = 0
function checkNum() {
let numVal = +prompt('Введите значение', '')
if (!isNaN(numVal)) {
// checkNum() // было так
arr.push(numVal) // добавляем элемент в массив
console.log(arr)
checkNum() // только после этого вызываем функцию checkNum
} else {
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
console.log(sum)
}
}
checkNum()
}
Код не работал потому что "вся полезная работа" откладывалась из за преждевременного вызова checkNum. А поскольку вызов рекурсивный, то сложно заметить такую ошибку и вообще понять что происходит в коде. Но в принципе ваш подход рабочий.
То что в консоли бывает undefined - это потому что основная функция sumInput ничего не возвращает явно (нет return). Но такие функции в JS всё же возвращают значение, просто оно не определено - undefined.
P.S.: Чтобы выполнить остальные условия из задания (пуcтая строка, кнопка Отмена), можно сделать так:
let val = prompt('Введите значение', ''); // сохраняем оригинальное значение
let numVal = Number(val); // приводим тип к числу, можно и через +val, как у вас
/*
расширяем условие проверки полученного значения
1. Если приведённая к типу число переменная не является числом
2. И если переменная не null (так будет в случае нажатия Отмена)
3. И если тип оригинального значения - строка и после удаления пробелов сохраняет длину (не пустая строка)
*/
if (!isNaN(numVal) && (val !== null) && (typeof val == 'string' && val.trim().length)) {
Всё это можно красивее написать, но потребуется сильнее изменить структуру кода.