Tipagem de callbacks em TypeScript: como definir um tipo para uma função de manipulador

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como parar de usar any para callbacks e começar a viver: guia completo para tipagem de funções de manipulador em TypeScript

\n\n

Você já escreveu algo como callback: any nos parâmetros de um método? Se sim — bem-vindo ao clube. Se não — ou você é um gênio, ou está apenas começando sua jornada em TypeScript. Brincadeira. Mas toda brincadeira tem um fundo de verdade: de acordo com o Stack Overflow, a pergunta "How to define type for a function callback (as any function type, not universal any)" acumula milhares de visualizações. E não é por acaso.

\n\n

O problema é que any é como um buraco negro: ele suga toda a segurança de tipos do seu código. Você perde o autocompletar, a verificação de argumentos e a capacidade de detectar bugs em tempo de compilação. Mas o pior é que any como tipo de callback mata a própria ideia do TypeScript. Vamos entender como tipar corretamente uma função callback em um parâmetro de método, para que o código seja seguro e elegante.

\n\n

Por que Function não é melhor que any?

\n\n

O primeiro impulso de um iniciante é usar o tipo embutido Function. Tipo, é o tipo "qualquer função", então serve. Mas não. Function é um tipo tão "lixo" quanto any. Ele não fornece nenhuma informação sobre a assinatura: quantos parâmetros a função aceita, o que retorna, quais são os tipos dos argumentos. Você está apenas dizendo ao compilador: "Confie em mim, eu sei o que estou fazendo". Spoiler: geralmente você não sabe.

\n\n
// Ruim: nenhuma verificação de tipos\nfunction processData(callback: Function) {\n    callback(42, "hello"); // Erro? Quem sabe\n}
\n\n

Com essa abordagem, você perde todas as vantagens da tipagem estática. Vamos corrigir isso.

\n\n

Passo 1. Tipagem básica de callback: simples e clara

\n\n

A maneira mais simples e correta é declarar o tipo da função diretamente no parâmetro. Para isso, usa-se a sintaxe de arrow function (parâmetros) => tipo_retornado. Isso é o function type em TypeScript.

\n\n
// Bom: definimos explicitamente a assinatura\nfunction fetchData(url: string, onSuccess: (data: string) => void): void {\n    // ... alguma lógica\n    const result = "Dados do servidor";\n    onSuccess(result);\n}\n\n// Uso — com autocompletar e verificação\nfetchData("/api/users", (data) => {\n    console.log(data.toUpperCase()); // data — string, tudo ok\n});
\n\n

Observe o void no tipo de retorno. Isso significa que não esperamos um valor específico do callback. Se o callback retornar algo, será ignorado. Se você espera um resultado, use um tipo específico.

\n\n

Passo 2. Callback com múltiplos parâmetros

\n\n

Frequentemente, callbacks aceitam mais de um argumento. Por exemplo, um manipulador de erros ou um evento com dados. Aqui é igualmente simples — listamos todos os parâmetros separados por vírgula.

\n\n
// Tipo para callback com erro e resultado\nfunction loadUser(\n    userId: number,\n    callback: (error: Error | null, user: { name: string; age: number } | null) => void\n): void {\n    // ... lógica de carregamento\n    const user = { name: "Ana", age: 30 };\n    callback(null, user);\n}\n\n// Uso\nloadUser(42, (err, user) => {\n    if (err) {\n        console.error("Erro:", err.message);\n        return;\n    }\n    if (user) {\n        console.log(`Olá, ${user.name}!`);\n    }\n});
\n\n

Viu como o TypeScript sugere automaticamente os tipos de err e user? Isso é a tipagem de função callback em ação. Sem any, sem mágica — apenas verificação rigorosa.

\n\n

Passo 3. Criando tipos reutilizáveis para callbacks

\n\n

Se o mesmo tipo de callback é usado em vários lugares, não precisa duplicá-lo toda vez. Extraia-o para um type alias ou interface separado. Isso melhora a legibilidade e facilita a manutenção.

\n\n
// Declara                

Blogs

Book Recommendations