Médio TypeScript

Assertion function para validar entrada

Enunciado

Crie uma função assertIsNumber que recebe um valor unknown e usa asserts value is number. Se o valor não for número, lance um erro com a mensagem 'Valor não é número'. Depois, use-a para validar uma entrada e somar 10.

Requisitos

  • A função deve ter assinatura (value: unknown): asserts value is number.
  • Deve lançar Error com a mensagem exata 'Valor não é número' se a validação falhar.
  • O programa principal deve chamar a função com um número e imprimir o resultado da soma.

Código inicial

function assertIsNumber(value: unknown): asserts value is number {
  // implemente
}

const entrada: unknown = 5;
// chame assertIsNumber e some 10

Saída esperada

15
Ver dica

Use typeof value !== 'number' para verificar e lance um Error.

Mostrar solução
function assertIsNumber(value: unknown): asserts value is number {
  if (typeof value !== 'number') {
    throw new Error('Valor não é número');
  }
}

const entrada: unknown = 5;
assertIsNumber(entrada);
console.log(entrada + 10); // entrada é number

Passo a passo

  1. Declaramos assertIsNumber com o tipo de retorno asserts value is number. Isso é uma assertion function: se ela não lançar erro, o TypeScript assume que value é number.
  2. Dentro da função, verificamos typeof value !== 'number'. Se for verdadeiro, lançamos um Error com a mensagem especificada.
  3. No código principal, temos entrada do tipo unknown.
  4. Chamamos assertIsNumber(entrada). Como entrada é 5, a função não lança erro.
  5. Após a chamada, o TypeScript estreita entrada para number.
  6. Somamos entrada + 10 e imprimimos 15.

Por que funciona

Assertion functions são como predicados, mas em vez de retornar booleano, elas garantem a condição após a chamada. Se a função retornar normalmente, o compilador sabe que o tipo é aquele declarado. Isso é útil para validar dados externos (APIs, JSON) sem repetir verificações.

Erros comuns

  • Esquecer o asserts: function assertIsNumber(value: unknown): value is number não é uma assertion function; o TypeScript não estreita após a chamada.
  • Não lançar erro: se a função não lançar exceção quando a condição é falsa, o TypeScript ainda estreita, mas o código pode quebrar em tempo de execução.
  • Usar assertion function em expressões: ela deve ser chamada como statement, não dentro de um if.

Outra forma de resolver

Usar um type predicate e verificar manualmente:

function isNumber(value: unknown): value is number {
  return typeof value === 'number';
}

if (isNumber(entrada)) {
  console.log(entrada + 10);
} else {
  throw new Error('Valor não é número');
}

Essa forma é mais verbosa, mas evita exceções.

Saída esperada

15