Yeah, more practically speaking, this “flattening” behavior of nullable(nullable(foo)) = nullable(foo) makes type checking much harder. This is one of the things that’s subtle and hard to get right when you tackle a type system on top of an existing dynamic language. The general case also induces horrible type checking performance.
Another example of flattening would be JS’ promises, where awaiting on nested promises “flattens” every level into one (in FP jargon, it’s map and bind combined into one function).
With the right sugar, the non-flattening version, option type, is actually _much_ better for not just type checking, but also developer ergonomics. Consider if you want to distinguish a map missing a value, or having a value that happens to be null. Or an iterator that asks you to return null to signal termination, but you just happen to want to provide the value null.