There were better languages but Unix won, and with that - C. A mistake we (whoever “we” are) repeated with JavaScript - we let the language win that was “there”, not the one we really needed.
Worse is better. Ease of deployment over ease of development.
As for the Q: why design languages with null (that is - incomplete or flawed type systems) now? I have o idea. I think the reasoning is that “worse is better” succeeded for JS, php, C, so it’s a viable path.
“Maybe an X” and “Definitely an X” are more different than string and number. If a language pretends string and number are distinct but at the same time has no distiction for “maybe X” - then it doesn’t have a very good type system.
Note that it doesn’t necessarily need to avoid null values for this. Non-nullables is mostly equivalent although less elegant. That is, “String s” means a string or null, while “String! s” means a non-null string (example from a C# vNext syntax).