Médio TypeScript

Par genérico com valor padrão

Enunciado

Crie uma função genérica criarPar que recebe dois argumentos de tipos diferentes e retorna uma tupla [primeiro, segundo]. O segundo tipo deve ter valor padrão string caso não seja inferido. A função deve aceitar o segundo argumento como opcional.

Requisitos

  • A função deve se chamar criarPar.
  • Deve ter dois parâmetros de tipo: T e U = string.
  • O segundo parâmetro da função deve ser opcional (b?: U).
  • O retorno deve ser uma tupla [T, U | undefined].
  • Deve funcionar com e sem o segundo argumento.

Código inicial

// Complete a função
function criarPar(/* ... */) {
  // ...
}

console.log(criarPar(1, "dois"));
console.log(criarPar(3));
console.log(criarPar("a", true));

Saída esperada

[ 1, 'dois' ]
[ 3, undefined ]
[ 'a', true ]
Ver dica

Declare <T, U = string>, o segundo parâmetro como b?: U e retorne [a, b] com tipo [T, U | undefined].

Mostrar solução
// Função genérica com dois parâmetros de tipo, o segundo com valor padrão
function criarPar<T, U = string>(a: T, b?: U): [T, U | undefined] {
  return [a, b];
}

console.log(criarPar(1, "dois")); // T=number, U=string (inferido)
console.log(criarPar(3));         // T=number, U=string (padrão), b=undefined
console.log(criarPar("a", true)); // T=string, U=boolean (inferido)

Passo a passo

  1. Declaramos criarPar com dois parâmetros de tipo: <T, U = string>. O = string define o valor padrão para U.
  2. O primeiro parâmetro a é do tipo T e é obrigatório.
  3. O segundo parâmetro b é opcional (b?: U), podendo ser omitido.
  4. O tipo de retorno é uma tupla [T, U | undefined], pois b pode ser undefined.
  5. Dentro da função, retornamos [a, b] diretamente.
  6. Na primeira chamada, U é inferido como string porque passamos "dois".
  7. Na segunda chamada, U não é inferido, então usa o padrão string; b fica undefined.
  8. Na terceira, U é inferido como boolean.

Por que funciona

O valor padrão U = string só é aplicado quando o tipo não pode ser inferido a partir dos argumentos. Como b é opcional, se não for passado, o TypeScript usa o padrão para U. A tupla de retorno inclui undefined para refletir a ausência do segundo valor. Isso mantém a segurança de tipos mesmo com parâmetros opcionais.

Erros comuns

  • Não tornar b opcional: function criarPar<T, U = string>(a: T, b: U) exige o segundo argumento, então criarPar(3) dá erro de compilação. Use b?: U.
  • Retornar [T, U] em vez de [T, U | undefined]: o compilador reclamará que b pode ser undefined. Ajuste o tipo de retorno.
  • Esquecer o valor padrão: sem = string, criarPar(3) infere U como unknown ou dá erro. O padrão resolve isso.

Outra forma de resolver

Você pode usar sobrecargas de função, mas genéricos com valor padrão são mais concisos. Alternativamente, use um objeto de opções:

function criarPar<T, U = string>(a: T, opcoes?: { b?: U }): [T, U | undefined] {
  return [a, opcoes?.b];
}

É preferível quando há muitos parâmetros opcionais.

Saída esperada

[ 1, 'dois' ]
[ 3, undefined ]
[ 'a', true ]