De fato existe muita confusão entre os termos. Infelizmente na internet se acha muito material que confunde as formas de tipagem, e o erro se propaga (a história da mentira contada tantas vezes que se torna "verdade").
Mas enfim, aqui tem um post que discute sobre as diferentes formas de tipagem. E também tem links para outras referências, as principais são essa e essa.
Só pra constar, segue um trecho da resposta que dei no primeiro link:
Existem tipagem estática e dinâmica, e tipagem fraca e forte, e é possível ter combinações (uma linguagem pode ter tipagem estática e forte, ou dinâmica e forte, ou estática e fraca, ou dinâmica e fraca).
Tipagem estática é quando uma variável não pode mudar seu tipo. Por exemplo, em Java, se eu definir que uma variável é de um tipo, não posso atribuir um valor de outro tipo (exceto se forem compatíveis, como no caso de sub-classes, por exemplo):
int x = 1;
x = "abc";
Tipagem dinâmica é quando a variável pode mudar o tipo. Por exemplo, em JavaScript:
var x = 1;
x = "abc";
Já as tipagens forte e fraca não são conceitos bem definidos e aceitos universalmente, e por vezes são confundidos com tipagem estática e dinâmica. De qualquer forma, a "força" da tipagem costuma estar associado ao fato de um dado poder ser tratado como se fosse de outro tipo. Em C, por exemplo, vc pode gravar um int
e acessá-lo como se fosse um ponteiro, entre outras maluquices que embora possíveis, nem sempre são úteis. Ou seja, C tem tipagem estática (uma variável não pode mudar o tipo) e fraca (um dado pode ser acessado como se fosse de outro tipo).
Também existem as linguagens que fazem coerção automática de tipos, como por exemplo PHP, na qual comparar um número com uma string pode ser verdadeiro (1 == "1"
- um dos valores é convertido para o tipo do outro, e depois é feita a comparação). Nesse caso, seria tipagem fraca (um dado é acessado como se fosse de outro tipo), além de ser dinâmica (em PHP, uma variável pode mudar seu tipo).
Já Python tem tipagem dinâmica e forte: uma variável pode mudar o tipo, mas o valor não pode ser acessado como se fosse de outro (ao contrário de PHP, em Python 1 == "1"
é falso), não há coerção automática.
Ou seja, o fato de inferir o tipo sem precisar declará-lo não indica se a tipagem é fraca ou forte, e nem se é estática ou dinâmica. Java, C# e JavaScript fazem inferência de tipos (var x = 1
é válido nas três, se considerarmos a partir do Java 10), mas as duas primeiras possuem tipagem forte e estática, enquanto a última tem tipagem fraca e dinâmica. Python e PHP também fazem inferência e não precisa declarar o tipo, e ambas possuem tipagem dinâmica (vc pode atribuir um valor de outro tipo na mesma variável), mas Python tem tipagem forte, enquanto PHP tem fraca.
Mas claro que na verdade o buraco é mais embaixo, e sugiro esta leitura, que é um ótimo ponto de partida para um aprofundamento maior sobre o tema.