This is exactly why I never recommend TypeScript to new developers.
A similar problem (that used to be worse) with people learning JavaScript is the lack of separation between JavaScript and the DOM + browser APIs. 10+ years ago, people have told me how much they hated JavaScript and when probed about it further, would admit that it’s actually the DOM or new/inconsistent browser APIs that have caused issued.
JS has a number of its own flaws and quirks, yes, but there are two fundamental issues that make it harder to approach as a new learner (as opposed to, to say, Python) are how tightly coupled it has historically been to it’s primarily application case and how high or low level is this language?
The idea that someone is good at another language so they'll automatically be good at another is a common misconception. In fact, they're likely to be worse because they're less likely to spend time trying to learn things from the ground up and less likely to write idiomatic code.
It's especially bad with js/ts because of it's popularity (so lots of new programmers that complain about how NaN doesn't equal itself), and because it's the defacto web language so lots of people are forced to use it as a secondary language that don't want to spend time learning it.
Care to provide what you mean?
Strict TS won't compile pretty much any type-unsafe operation.
It's not perfect, the standard libraries are a bit too unsafe type wise, exceptions are untyped and need Either/Result-like data types to be handled but it's an extremely powerful language if you know it and it's ecosystem.
Most people though don't even bother reading the docs and can't tell you what a mapped type is or what is a disjointed union, etc.
As soon as you have third party code calling your methods all bets are off. It could be JS calling your methods, or there simply is a hidden cast somewhere.
This is the moment that you realize that type annotations really are just a compile-time fiction, much like Python. At least in my definition, this is weak typing as the variable is physically capable of changing to any type at runtime, despite its type annotations.
In case of C++ this would lead to desastrous memory corruption. If all data is dynamic you can't have a safe program as data on the stack must be monomorphic or you corrupt nearby memory.
Naturally, you can defend against hostile input via excessive defensive programming (asserting against nulls, asserting against wrong types etc.). Or you simply use a strong static typed language.
(Like expecting that just because you declared something as type X, that it guarantees at runtime it will always be type X, but it won't. You may get data from an API that _says_ it returns type X but the contents don't match. That can be valid code that compiles and has weird runtime behavior)