Cleanest and easiest approach that came to mind:
const numberText = {
1: 'one',
2: 'two',
3: 'three',
4: 'four',
5: 'five',
6: 'six',
7: 'seven',
8: 'eight',
9: 'nine',
10: 'ten',
11: 'eleven',
12: 'twelve',
13: 'thirteen',
14: 'fourteen',
15: 'fifteen',
16: 'sixteen',
17: 'seventeen',
18: 'eighteen',
19: 'nineteen',
20: 'twenty',
30: 'thirty',
40: 'forty',
50: 'fifty',
60: 'sixty',
70: 'seventy',
80: 'eighty',
90: 'ninety',
100: 'hundred',
1000: 'thousand',
}
const numberValues = Object.keys(numberText)
.map((val) => Number(val))
.sort((a, b) => b - a)
const convertNumberToEnglishText = (n) => {
if (n === 0) return 'zero'
if (n < 0) return 'negative ' + convertNumberToEnglishText(-n)
let num = n
let text = ''
for (const numberValue of numberValues) {
const count = Math.trunc(num / numberValue)
if (count < 1) continue
if (numberValue >= 100) text += convertNumberToEnglishText(count) + ' '
text += numberText[numberValue] + ' '
num -= count * numberValue
}
if (num !== 0) throw Error('Something went wrong!')
return text.trim()
}