Tecnologias/01 - Linguagens/02 - TypeScript3 min
Validação de Dados em TypeScript
Definição
Validação em execução confere os dados que realmente chegaram: propriedades, tipos, formatos e regras do domínio. É necessária nas fronteiras da aplicação, como JSON de uma requisição, respostas de terceiros e mensagens de uma fila.
unknown representa um valor cujo tipo ainda não foi demonstrado. Ele aceita qualquer
entrada, mas exige refinamento antes de operações específicas. any permite essas
operações sem a mesma verificação.
Referência: unknown.
Exemplo completo
O parser recebe algo desconhecido, valida os campos e constrói um objeto do domínio. Ele rejeita entradas inválidas e seleciona explicitamente os campos que serão usados.
type Item = { nome: string; quantidade: number };
function lerItem(entrada: unknown): Item {
if (typeof entrada !== "object" || entrada === null) {
throw new Error("Item deve ser um objeto");
}
if (!("nome" in entrada) || typeof entrada.nome !== "string") {
throw new Error("Nome deve ser texto");
}
if (!("quantidade" in entrada) || typeof entrada.quantidade !== "number") {
throw new Error("Quantidade deve ser numérica");
}
const nome = entrada.nome.trim();
const quantidade = entrada.quantidade;
if (!nome || !Number.isInteger(quantidade) || quantidade <= 0) {
throw new Error("Nome vazio ou quantidade inválida");
}
return { nome, quantidade };
}
const entrada: unknown = JSON.parse('{"nome":"Caderno","quantidade":2}');
const item = lerItem(entrada);
console.log(item.quantidade * 10); // 20
As verificações de objeto, propriedades e tipos permitem que o compilador acompanhe o refinamento. A construção do resultado evita repassar campos desconhecidos. Referência: Narrowing.
Por que uma asserção não resolve
entrada as Item afirma um tipo ao compilador, mas não testa o conteúdo.
JSON.parse verifica a sintaxe JSON; não verifica sozinho o contrato de Item.
Limites da validação
Ter um formato válido não significa que a operação é permitida. Um pedido pode conter um identificador bem formado e ainda apontar para um recurso de outro usuário. Autorização e regras que dependem do banco continuam sendo verificações próprias. Em esquemas extensos, um validador por schema pode centralizar regras; os testes devem incluir casos inválidos e condições de fronteira.
Aprofundamento aplicado
Parsing, domínio e autorização são etapas distintas
Considere { "produtoId": "p1", "quantidade": 2 } em uma compra:
- O parser verifica objeto, identificador e inteiro positivo dentro de um limite.
- A regra de domínio verifica disponibilidade e condições da compra.
- A autorização verifica se o solicitante pode executar a operação.
- Uma escrita condicional ou transação protege o estoque contra concorrência.
Ler estoque antes e validá-lo na aplicação não impede outra compra de consumi-lo antes da gravação. A condição que precisa permanecer verdadeira deve participar da escrita. Veja 3. Consistência e Transações no DynamoDB e 3. MVCC e Isolamento na Prática.
Casos que um teste feliz esconde
| Entrada | Decisão esperada para quantidade |
|---|---|
2 |
Aceitar, se dentro do limite do domínio |
"2" |
Rejeitar ou converter explicitamente, conforme contrato |
0, -1, 1.5 |
Rejeitar |
| Número acima do inteiro seguro | Rejeitar para contagem exata |
| Campo ausente | Informar erro identificando o campo |
| Propriedade extra | Descartar ou rejeitar conforme política declarada |
Number.isInteger não é suficiente para exigir inteiro seguro; quando necessário,
use Number.isSafeInteger e um teto do domínio. JSON não representa NaN nem infinito
como literais válidos, mas entradas internas JavaScript podem carregar esses valores.
Exercício: rode a tabela contra lerItem e acrescente a regra de quantidade máxima.
Resultado esperado: cada rejeição decorre de uma regra explícita, sem depender de
coerções acidentais como converter string vazia para zero.
Referência: Number.isSafeInteger.
Relacionado: 4. Unions, Narrowing e Valores Ausentes · 5. Generics e Tipos Utilitários.
Parte de TypeScript