<h2>O que são Type Hints em Python</h2>
<p>Type hints (anotações de tipo) são uma forma de indicar explicitamente qual tipo de dado uma variável, parâmetro de função ou retorno de função deve possuir. Introduzidas na PEP 484 (Python 3.5), elas permitem que você especifique tipos sem alterar o comportamento da linguagem em tempo de execução. Python continua sendo dinamicamente tipado, mas as anotações servem como documentação viva e como base para ferramentas de análise estática.</p>
<p>Quando você escreve <code>nome: str = "João"</code>, está dizendo: "a variável <code>nome</code> deve conter uma string". Isso não impede que você atribua um inteiro depois (Python não vai reclamar em runtime), mas comunica sua intenção e permite que ferramentas como <code>mypy</code> detectem problemas potenciais antes do código ser executado. Pense em type hints como um contrato que você estabelece com quem vai usar seu código — inclusive você mesmo, meses depois.</p>
<h2>Sintaxe Fundamental e Tipos Básicos</h2>
<h3>Anotações em Variáveis</h3>
<p>A forma mais simples é anotar uma variável com seu tipo esperado. Use a sintaxe <code>nome: tipo</code> antes da atribuição ou logo após:</p>
<pre><code class="language-python">idade: int = 25
nome: str = "Maria"
altura: float = 1.75
ativo: bool = True</code></pre>
<p>Se você não atribuir um valor imediatamente, a anotação fica como documentação:</p>
<pre><code class="language-python">email: str
Pode ser atribuído depois
email = "usuario@example.com"</code></pre>
<h3>Anotações em Funções</h3>
<p>As anotações em funções especificam os tipos dos parâmetros e do retorno. Use <code>-></code> para indicar o tipo de retorno:</p>
<pre><code class="language-python">def calcular_desconto(preco: float, percentual: float) -> float:
return preco * (1 - percentual / 100)
resultado = calcular_desconto(100.0, 10.0)
print(resultado) # 90.0</code></pre>
<p>Quando uma função não retorna nada, use <code>None</code>:</p>
<pre><code class="language-python">def exibir_mensagem(texto: str) -> None:
print(f"Mensagem: {texto}")
exibir_mensagem("Olá") # Olá</code></pre>
<h3>Tipos Primitivos</h3>
<p>Os tipos básicos que você já conhece do Python funcionam como anotações:</p>
<pre><code class="language-python">numero: int
texto: str
decimal: float
booleano: bool
nada: None</code></pre>
<h2>O Módulo <code>typing</code> e Tipos Avançados</h2>
<h3>Containers Tipados</h3>
<p>Quando você trabalha com listas, dicionários e outros containers, o módulo <code>typing</code> permite especificar que tipo de elemento eles contêm. Sem <code>typing</code>, apenas <code>list</code> não diz se é uma lista de inteiros ou strings:</p>
<pre><code class="language-python">from typing import List, Dict, Tuple, Set
numeros: List[int] = [1, 2, 3]
nomes: List[str] = ["Ana", "Bruno", "Carlos"]
configuracoes: Dict[str, int] = {"timeout": 30, "tentativas": 3}
coordenadas: Tuple[float, float] = (10.5, 20.3)
ids_unicos: Set[str] = {"user1", "user2"}</code></pre>
<p>Isso é muito mais preciso do que apenas escrever <code>list</code>. Ferramentas de análise podem agora verificar se você está tentando adicionar uma string a uma lista de inteiros:</p>
<pre><code class="language-python">def processar_ids(ids: List[str]) -> None:
for id_item in ids:
print(f"ID: {id_item}")
processar_ids(["a", "b", "c"]) # Correto
processar_ids([1, 2, 3]) # mypy alertaria aqui</code></pre>
<h3>Union e Optional</h3>
<p><code>Union</code> permite que uma variável ou retorno tenha múltiplos tipos possíveis. <code>Optional</code> é um atalho para "tipo ou <code>None</code>":</p>
<pre><code class="language-python">from typing import Union, Optional
def encontrar_usuario(id_usuario: int) -> Optional[str]:
usuarios = {1: "Alice", 2: "Bob"}
return usuarios.get(id_usuario) # Retorna string ou None
resultado = encontrar_usuario(1)
print(resultado) # Alice
resultado = encontrar_usuario(999)
print(resultado) # None</code></pre>
<p><code>Union</code> é útil quando múltiplos tipos são válidos:</p>
<pre><code class="language-python">def converter_para_inteiro(valor: Union[str, int]) -> int:
if isinstance(valor, str):
return int(valor)
return valor
print(converter_para_inteiro("42")) # 42
print(converter_para_inteiro(42)) # 42</code></pre>
<h3>Generic Types e Callable</h3>
<p>Para funções que aceitam outras funções como parâmetro, use <code>Callable</code>:</p>
<pre><code class="language-python">from typing import Callable
def aplicar_operacao(a: int, b: int, operacao: Callable[[int, int], int]) -> int:
return operacao(a, b)
def somar(x: int, y: int) -> int:
return x + y
resultado = aplicar_operacao(5, 3, somar)
print(resultado) # 8</code></pre>
<p>Aqui, <code>Callable[[int, int], int]</code> significa: "uma função que recebe dois inteiros e retorna um inteiro".</p>
<h2>Benefícios Práticos e Ferramentas</h2>
<h3>Detecção de Erros com mypy</h3>
<p>O <code>mypy</code> é um verificador de tipo estático que analisa seu código Python sem executá-lo. Ele encontra incompatibilidades de tipo que poderiam causar bugs:</p>
<pre><code class="language-python"># arquivo: exemplo.py
def saudacao(nome: str) -> str:
return f"Olá, {nome}!"
resultado = saudacao(123) # Erro: int não é str</code></pre>
<p>Executando <code>mypy exemplo.py</code>, ele detecta o problema:</p>
<pre><code>exemplo.py:4: error: Argument 1 to "saudacao" has incompatible type "int";
expected "str"</code></pre>
<p>Sem type hints, esse erro passaria desapercebido até a execução. Com type hints, você encontra o problema imediatamente durante desenvolvimento.</p>
<h3>Melhor Experiência do IDE</h3>
<p>IDEs como PyCharm e VS Code usam type hints para oferecer autocompletar mais preciso e inteligente. Quando você digita <code>usuarios.</code>, o editor sabe que <code>usuarios</code> é uma <code>List[Dict[str, str]]</code> e sugere apenas métodos e chaves relevantes:</p>
<pre><code class="language-python">from typing import List, Dict
usuarios: List[Dict[str, str]] = [
{"nome": "Alice", "email": "alice@example.com"},
{"nome": "Bob", "email": "bob@example.com"}
]
Ao digitar usuarios[0]., o IDE sabe que é um Dict
e sugere as chaves "nome" e "email"
primeira_usuario = usuarios[0]
print(primeira_usuario["nome"]) # Autocompletar funciona perfeitamente</code></pre>
<h3>Documentação Viva</h3>
<p>Type hints servem como documentação inline que nunca fica desatualizada:</p>
<pre><code class="language-python">def buscar_usuario_por_email(email: str) -> Optional[Dict[str, any]]:
"""
Busca um usuário no banco de dados.
Args:
email: O e-mail do usuário a buscar
Returns:
Dicionário com dados do usuário ou None se não encontrado
"""
implementação
pass</code></pre>
<p>Qualquer desenvolvedor lendo seu código sabe imediatamente o que a função espera e o que ela retorna, sem precisar ler a documentação completa.</p>
<h3>Refatoração Segura</h3>
<p>Quando você precisa alterar tipos de dados, as anotações ajudam a identificar todos os locais afetados:</p>
<pre><code class="language-python"># Antes
def calcular_total(precos: List[float]) -> float:
return sum(precos)
Depois, precisa retornar inteiro também?
def calcular_total(precos: List[float]) -> Tuple[float, int]:
total = sum(precos)
return total, len(precos)
mypy alertará todos os locais que usam essa função</code></pre>
<h2>Conclusão</h2>
<p>Type hints em Python não são obrigatórios, mas oferecem benefícios concretos: detecção de erros mais cedo, melhor experiência em IDEs, documentação clara e refatorações mais seguras. Eles são especialmente valiosos em projetos maiores e em times, onde a comunicação clara sobre contratos de dados é fundamental. A chave é começar com tipos simples e ir adoptando tipos mais avançados conforme sua necessidade aumenta — Python flexível permite crescimento gradual sem impor rigidez desde o início.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.python.org/dev/peps/pep-0484/" target="_blank" rel="noopener noreferrer">PEP 484 — Type Hints</a></li>
<li><a href="https://docs.python.org/3/library/typing.html" target="_blank" rel="noopener noreferrer">Documentação oficial do módulo <code>typing</code></a></li>
<li><a href="https://mypy.readthedocs.io/" target="_blank" rel="noopener noreferrer">mypy: Static type checker for Python</a></li>
<li><a href="https://realpython.com/python-type-checking/" target="_blank" rel="noopener noreferrer">Real Python — Type Checking in Python</a></li>
<li><a href="https://www.python.org/dev/peps/pep-0586/" target="_blank" rel="noopener noreferrer">Python Enhancement Proposal 586 — Literal Types</a></li>
</ul>
<p><!-- FIM --></p>