Just FYI: If one wants his/her "programming language" to catch typing errors/violations/mismatches, one needs to use a language with strong typing, regardless of if the language itself supports static or dynamic typing.
Dynamic typing relies on being able to infer the types; this can be often achieved at compile time but in any case at runtime, if the platform is strongly typed, any type error will be caught. Then, after being caught, what could be done about it depends on your platform -- some platforms will die with an error; some others will die but allow you to inspect what happened; then others allow you to patch (correct) the error and continue.
Static typing requests you to explicitly declare types. This helps the compiler do as much checking as possible at compile-time. This has the added side benefit to increase the speed of the compile code, since less checking is needed at runtime.
Some systems are dynamically typed but weakly-typed. Examples are PHP and ES/Javascript.
Some systems are statically typed but fairly weakly-typed. The Kerninghan&Ritchie C language is an example.
Some systems are dynamically typed and strongly typed. Python is one of them, although it also has what is so-called "duck" typing.
Some systems support dynamic and (optional) static typing, and are strongly typed. Common Lisp is an example, as well as in Julia. In both cases (CL and Julia), static typing helps for increasing performance, and for achieving multiple dispatch (i.e. for Object-Oriented programming). CL is able to do compile-time checking as well, if the implementation supports it.
Some systems have fairly complete strong typing which relies on extensive static typing facilities. Haskell is an example.