Desafio TypeScript

Calculadora com tipo de função

Enunciado

Defina um tipo Operacao que representa uma função que recebe dois números e retorna um número. Crie uma função calcular que recebe uma operação e dois números, e retorna o resultado. Use parâmetros opcionais para permitir uma mensagem de erro personalizada. Teste com soma, subtração e multiplicação.

Requisitos

  • O tipo Operacao deve ser (a: number, b: number) => number.
  • A função calcular deve ter parâmetros: operacao: Operacao, a: number, b: number, e um parâmetro opcional mensagemErro?: string.
  • Se a ou b não forem números, deve lançar um erro com a mensagem fornecida ou uma padrão.
  • Deve retornar o resultado da operação.

Código inicial

type Operacao = (a: number, b: number) => number;

function calcular(operacao: Operacao, a: number, b: number, mensagemErro?: string): number {
  // Seu código aqui
}

Saída esperada

Soma: 5
Subtração: 1
Multiplicação: 6
Erro: Valores inválidos
Ver dica

Use typeof para verificar se os parâmetros são números. Lance um Error com a mensagem apropriada.

Mostrar solução
type Operacao = (a: number, b: number) => number;

function calcular(operacao: Operacao, a: number, b: number, mensagemErro?: string): number {
  if (typeof a !== "number" || typeof b !== "number") {
    throw new Error(mensagemErro ?? "Valores inválidos");
  }
  return operacao(a, b);
}

const soma: Operacao = (x, y) => x + y;
const subtracao: Operacao = (x, y) => x - y;
const multiplicacao: Operacao = (x, y) => x * y;

console.log("Soma:", calcular(soma, 2, 3));
console.log("Subtração:", calcular(subtracao, 5, 4));
console.log("Multiplicação:", calcular(multiplicacao, 2, 3));

try {
  calcular(soma, "2" as any, 3, "Valores inválidos");
} catch (e) {
  console.log("Erro:", (e as Error).message);
}

Passo a passo

  1. Definimos o tipo Operacao como uma função que recebe dois números e retorna um número.
  2. A função calcular recebe uma operacao desse tipo, dois números a e b, e um parâmetro opcional mensagemErro.
  3. Verificamos se a e b são realmente números; se não, lançamos um erro com a mensagem fornecida ou a padrão.
  4. Retornamos o resultado da chamada operacao(a, b).
  5. Criamos três operações usando arrow functions e as testamos.
  6. No final, forçamos um erro passando uma string como a para demonstrar o tratamento.

Por que funciona

O tipo Operacao permite passar qualquer função compatível. A verificação de tipos em tempo de execução (com typeof) complementa a checagem estática do TypeScript. O parâmetro opcional mensagemErro personaliza a mensagem de erro.

Erros comuns

  • Não verificar os tipos em tempo de execução: calcular(soma, "2" as any, 3) – sem a verificação, a operação pode concatenar strings em vez de somar.
  • Esquecer de tipar a operação: function calcular(operacao, a, b) – o TypeScript infere any, perdendo a segurança.
  • Usar mensagemErro sem ??: throw new Error(mensagemErro) – se não for passada, a mensagem fica undefined.

Outra forma de resolver

Usar um objeto com métodos em vez de funções separadas:

const operacoes = {
  soma: (a: number, b: number) => a + b,
  subtracao: (a: number, b: number) => a - b,
  multiplicacao: (a: number, b: number) => a * b,
};
console.log(calcular(operacoes.soma, 2, 3));

Saída esperada

Soma: 5
Subtração: 1
Multiplicação: 6
Erro: Valores inválidos