You are confusing explicit typing with static typing. "Static" means "compile-time checking". "Dynamic" means "defer checks to run-time". Some language implementations can disable run-time type checking if optional type annotations are added, such as in Typed Racket.
In other words, all the following combinations are possible:
- Implicit + dynamic + strong: Python
- Implicit + dynamic + weak: JavaScript
- Implicit + static + strong: Standard ML without type annotations
- Explicit + dynamic + strong: Elixir with type annotations
- Explicit + static + strong: Java
- Explicit + static + weak: C
I struggle to come up with examples for these... - Implicit + static + weak
- Explicit + dynamic + weak
... but I'm sure they exist, perhaps as historical languages from when type systems were less sophisticated. After all, "strong" and "weak" are entirely relative, constantly in flux, and exist on a continuum. In a couple decades, anything lacking dependent types might perhaps be considered "weakly typed".