The Google Closure type system is much saner on this front already. A variable of a declared type cannot be undefined. Nullable and non-nullable types are distinct: primitives are non-nullable by default, with an option to make them nullable (?string, ?number, etc.), and types deriving from Object are nullable by default, with an option to make them non-nullable (!Object, !MyType, etc.)
Of course JavaScript itself does not have a notion of nullable types, so touching any native API interfaces naturally leaves you with a bunch of nullable types where you may well know the value will never be null, so you are left trying to decide where to do nothing, where to add an assertion, and where to add a conditional branch. This ambiguity comes through the Closure API in many places that it would be nice to have a non-nullable type guarantee, but I suppose the library has evolved over time and further must be adaptable to a range of coding styles.
> touching any native API interfaces naturally leaves you with a bunch of nullable types where you may well know the value will never be null
If a native API really never returns null it can be declared as such in Closure's externs (equivalent of a header file). If it can return null then doing a routine null check will automatically add the non-nullable attribute when the check succeeds, no cast required.
You can flip the default. Back when I was using Closure Compiler, it was the expected convention on my team to mark most of your type annotations non-nullable.
you mean value types rather than primitives right? (Strings are objects)
It would be saner if everything was non null by default. There'd be no need for a ! then and no ambiguity for beginners around whether something is nullable or not. No downside for non-beginners either unless they're in the habit of using more nullable parameters/vars than non-nullable, which doesn't seem like a particularly good idea...
Agreed on the defaults, although you then have the problem of reconciling with the native JS type system. I'm unclear on what this PR does to address that for TS - in strict null check mode, can an e.g. Node be null by default? If so, does the native "Node" object then become "Node|null"? At some level this has to be addressed.
Native objects can never be null. If its an object, it already isnt null. Functions,property accessors etc. can return Node or null or undefined, which can be modelled accordingly on a per-function basis
Of course JavaScript itself does not have a notion of nullable types, so touching any native API interfaces naturally leaves you with a bunch of nullable types where you may well know the value will never be null, so you are left trying to decide where to do nothing, where to add an assertion, and where to add a conditional branch. This ambiguity comes through the Closure API in many places that it would be nice to have a non-nullable type guarantee, but I suppose the library has evolved over time and further must be adaptable to a range of coding styles.