TypeScript: funções como parâmetros com tipagem estrita — análise completa

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

TypeScript: funções como parâmetros com tipagem estrita — análise completa com exemplos

\n\n

Olá, colega! Se você já escreveu em JavaScript e passou uma função para outra função (por exemplo, em setTimeout ou Array.map), você já conhece o conceito de funções de ordem superior. Mas quando se trata de TypeScript, surge uma pergunta lógica: "É possível tipar estritamente a função que estou passando como parâmetro?". A resposta é sim, e este é um dos recursos mais poderosos da linguagem.

\n\n

Neste artigo, vamos analisar como declarar tipos de funções em TypeScript, como passá-las como argumentos e como não errar com as assinaturas. Você aprenderá a tornar o código não apenas seguro, mas também autodocumentado. Vamos lá!

\n\n

A propósito, esta é uma das perguntas mais populares no Stack Overflow (milhares de visualizações). Então, se você quer entender de uma vez por todas — está no lugar certo.

\n\n

Por que isso é importante: a tipagem estrita economiza tempo

\n\n

Imagine que você está escrevendo uma função que recebe outra função (callback). Sem tipos, você pode acidentalmente passar uma função com o número errado de argumentos ou com o valor de retorno incorreto. O TypeScript detecta esses erros em tempo de compilação, não em tempo de execução. É como um seguro para o seu código.

\n\n

Aqui está um exemplo que não funcionará sem tipos:

\n\n
// JavaScript (sem tipos) — o erro ocorrerá apenas em tempo de execução\nfunction processData(callback) {\n    const result = callback(10, 20);\n    console.log(result);\n}\n\n// Opa, passamos uma função com apenas um parâmetro\nprocessData((x) => x * 2); // NaN — porque o segundo parâmetro é undefined
\n\n

Com TypeScript, podemos especificar explicitamente qual assinatura o callback deve ter:

\n\n
// TypeScript — erro em tempo de compilação\nfunction processData(callback: (a: number, b: number) => number): void {\n    const result = callback(10, 20);\n    console.log(result);\n}\n\n// ✅ Correto\nprocessData((x, y) => x + y); // 30\n\n// ❌ Erro: O tipo '(x: number) => number' não é atribuível ao tipo '(a: number, b: number) => number'\n// processData((x) => x * 2);
\n\n

Legal, né? Agora vamos analisar todas as formas de declarar esses tipos.

\n\n

Forma 1: Assinatura inline (a mais simples)

\n\n

A forma mais direta é especificar a assinatura da função diretamente nos parâmetros. Isso é útil quando a função-parâmetro é usada apenas uma vez.

\n\n
// Função que recebe outra função com dois números e retorna uma string\nfunction formatNumbers(\n    a: number,\n    b: number,\n    formatter: (x: number, y: number) => string\n): string {\n    return formatter(a, b);\n}\n\n// Uso\nconst result = formatNumbers(5, 10, (x, y) => `Soma: ${x + y}`);\nconsole.log(result); // "Soma: 15"
\n\n

Vantagens: rápido, claro.
\nDesvantagens: se a assinatura se repetir, você terá que duplicar o código.

\n\n

Forma 2: Type alias para função (reutilizável)

\n\n

Se você usar a mesma assinatura em vários lugares, é melhor criar um type alias. Isso torna o código mais limpo e fácil de manter.

\n\n
// Declarando o tipo da função\ntype Callback = (error: Error | null, data: string) => void;\n\n// Função que recebe um Callback\nfunction fetchData(url: string, callback: Callback): void {\n    // Simulação de requisição assíncrona\n    setTimeout(() => {\n        if (url) {\n            callback(null, "Dados recebidos");\n        } else {\n            callback(new Error("URL vazia"), "");\n        }\n    }, 1000);\n}\n\n// Uso\nfetchData("/api/data", (err, data) => {\n    if (err) {\n        console.error("Erro:", err.message);\n    } else {\n        console.log("Sucesso:", data);\n    }\n});
\n\n

Observe que usamos void como tipo de retorno. Isso significa que a função pode não retornar

Blogs

Book Recommendations