Desafio TypeScript
Validador de campos com keyof e typeof
Enunciado
Crie um objeto formulario com campos nome (string), idade (number) e email (string). Implemente uma função validarCampo que recebe o objeto, uma chave e uma função de validação específica para o tipo daquele campo. A função deve retornar true se o valor passar na validação. Use tipos genéricos e indexados para garantir que a função de validação receba o tipo correto. Teste com três campos e imprima os resultados.
Requisitos
- O tipo da chave deve ser
keyof T. - A função de validação deve receber
T[K]como parâmetro. - A função
validarCampodeve retornarboolean. - O código deve compilar sem erros e imprimir
trueoufalsepara cada teste.
Código inicial
const formulario = {
nome: "",
idade: 0,
email: "teste@exemplo.com",
};
// Implemente validarCampo e os testes
Saída esperada
nome: false
idade: true
email: true
Ver dica
A assinatura pode ser function validarCampo<T, K extends keyof T>(obj: T, chave: K, validador: (valor: T[K]) => boolean): boolean. Retorne validador(obj[chave]).
Mostrar solução
const formulario = {
nome: "",
idade: 0,
email: "teste@exemplo.com",
};
// Valida se o campo atende à regra específica
function validarCampo<T, K extends keyof T>(
obj: T,
chave: K,
validador: (valor: T[K]) => boolean
): boolean {
return validador(obj[chave]);
}
// Testes com validadores específicos por tipo
const nomeValido = validarCampo(formulario, "nome", (v) => v.length > 0);
const idadeValida = validarCampo(formulario, "idade", (v) => v >= 18);
const emailValido = validarCampo(formulario, "email", (v) => v.includes("@"));
console.log(`nome: ${nomeValido}`);
console.log(`idade: ${idadeValida}`);
console.log(`email: ${emailValido}`);
Passo a passo
- Definimos
formulariocom três campos de tipos distintos. - A função
validarCampoé genérica emTeK extends keyof T. - O terceiro parâmetro é uma função
validadorque recebeT[K], o tipo exato do campo selecionado. - Dentro da função, chamamos
validador(obj[chave])e retornamos o booleano resultante. - No teste de
nome, o validador recebestringe verifica se o comprimento é maior que zero. - No teste de
idade, o validador recebenumbere verifica se é maior ou igual a 18. - No teste de
email, o validador recebestringe verifica se contém@. - Imprimimos os resultados no formato pedido.
Por que funciona
O uso de T[K] no parâmetro validador garante que a função de validação receba exatamente o tipo da propriedade escolhida. O TypeScript infere K a partir da string literal passada e verifica se o validador é compatível. Isso permite criar APIs flexíveis e seguras, sem casts e sem perda de tipagem.
Erros comuns
- Tipar o validador como
(valor: any) => boolean: perde a segurança e não demonstra o conceito. - Usar
keyof Tsem restringirK:function validarCampo<T>(obj: T, chave: keyof T, validador: (v: T[keyof T]) => boolean)faz o validador receber a união de todos os tipos, dificultando a escrita. - Passar uma chave inexistente:
validarCampo(formulario, "telefone", ...)gera erro de compilação. - Esquecer de retornar o resultado: a função deve retornar
validador(obj[chave]), não apenas chamá-lo.
Outra forma de resolver
Poderia usar um mapa de validadores por chave, mas a função genérica é mais flexível e reutilizável. Também é possível usar sobrecargas, mas os genéricos são mais limpos.
Saída esperada
nome: false
idade: true
email: true