OK, those are fair arguments.
I'm just going to point out an alternative solution to providing type assertions. In this thread, I had brought up an idea of using a "from" keyword, to allow arbitrary operations to happen during assignment. I believe @mmkal might be making a separate topic soon to discuss it more fully. This would allow us to do things like the following:
const assertNumb = n => {
if (typeof n !== 'number') throw new Error('Bad type!')
return n
}
function addNumbs(x from assertNumb, y from assertNumb) {
return x + y
}
// is the same as this:
function addNumbs(x_, y_) {
let x = assertNumb(x_)
let y = assertNumb(y_)
return x + y
}
A library of different type assertions could be created, that could be inlined into any declaration position. These assertions could become very rich, e.g. you could assert that a number was even, or that a string matched a regex, etc.
Just an alternative direction I thought I would point out.
It doesn't help with the scenario of making sure a local variable stays the same type, even after assignment. But, IMO, that's not a big deal, because ideally reassignment should be kept to a minimum. I would do zero reassignment if the language provided the facilities to do so, but things like try-catch don't make it easy to avoid reassignment.
It also doesn't help with object members. This would be a place where your proposal has certain strengths over the one I'm proposing.