Not just more successful in terms of adoption, but safer even than many "native" typed languages. You can never really tell if a random method in Java can return null without reading through its source and the transitive source of anything it may potentially call. And with dynamic dispatch, this becomes literally impossible. That Java virus of null contaminates other JVM languages like Scala too. It's even worse because you can have Option types that are themselves potentially nullable. Some/None/null is a terrible situation to be stuck in.
And then the expressiveness of the type system there is also really pragmatic. You can't natively express union types in Java and many other static languages without writing your own Either monad implementation. Instead, you often wind up with code that has objects with a hodge-podge of field sets that are nullable.
It's nothing short of miraculous how well the null-safety situation is in TypeScript. It's built on the back of community-driven types in DefinitelyTyped where the maintainers of libs often aren't the ones writing and keeping types up to date. Nowadays, types are becoming more and more first-party, but it still amazes me how we got to this point.
And then the expressiveness of the type system there is also really pragmatic. You can't natively express union types in Java and many other static languages without writing your own Either monad implementation. Instead, you often wind up with code that has objects with a hodge-podge of field sets that are nullable.
It's nothing short of miraculous how well the null-safety situation is in TypeScript. It's built on the back of community-driven types in DefinitelyTyped where the maintainers of libs often aren't the ones writing and keeping types up to date. Nowadays, types are becoming more and more first-party, but it still amazes me how we got to this point.