The other commenter related the types to normal binary operations, which I think explains why (T | Null) | Null can't be distinguished from T | (Null | Null). Another way of thinking about it is by asking what "untagged unions" actually means, and in the context of languages like Typescript, it generally means "unions where the tag is the type of the object". ("Untagged" here is a bit of a misnomer.) But if the tag is the type of the object, how do I distinguish between two different nulls? They both have the same type (the Null-Type), which means they both have the same tag in the union, which means they're the same.
What you say about `Option<Player?>` is a good point though. If we want to distinguish between the different results, we need an explicit Option type. But now we've got Option _and_ we've got nullable types. Which should we use? They're both doing the same thing (i.e. marking where a type may be present but might not be), so why do we need both?
In practice, my impression that nullable types are really good for integrating with languages that already have unchecked nulls in then, either for historical reasons (like Java) or because they're dynamic languages (like Python or Javascript). It's a way of acknowledging the null value in the type system without demanding that all the code that been interacting with nulls be rewritten.
However, if you were going to write your own language from scratch, it's difficult to see why you would allow nullables to exist when the Option type does pretty much everything that nullables can, but with more clarity for cases of "nested nullability". You can also still add syntax sugar for it (Rust is going down this route, for example), but you don't have to special case nullability to the same extent.