Sim, muito importante sempre lembrar como o TS não fica no produto final e não impede nada de acontecer.
O que a gente sempre acaba tendo que fazer é garantir que os inputs vindos de fora do App acabem sendo convertidos pros tipos que a gente quer, o que é trackeado com TS e feito sempre com JS. Isso já evitaria, virtualmente, todos os casos.
Resumindo: use o TS como detector de possíveis entradas e garanta em JS que elas serão devidamente tratadas.
Uma possível abordagem seria verificando os tipos que nós não temos total controle (externos) e até variáveis de ambiente:
const sum = (a: unknown, b: unknown) => {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new Error('All params must be numbers');
}
return a + b;
};
- Dessa forma, mesmo após a compilação, o método
sum
sempre verificará os tipos.
Outra forma comum e geralmente menos verbosa, seria forçar os tipos. Por exemplo, Number(a) + Number(b)
.
🔐 Ao que se refere à segurança, particularmente eu sempre uso unknown
para todo e qualquer dado que venha do usuário.
Vale considerar que esse exemplo considera um cenário onde não temos controle do que o usuário pode enviar nos parâmetros
a
eb
.Em abordagens onde temos controle de todas as pontas, nem sempre é preciso ir tão longe 🧙🏻
Ainda assim, apenas garantir que os tipos agora são de fato numéricos, não garante que a soma sempre trará os resultados corretos.
Pessoalmente falando, costumo manter um equilíbrio entre testes unitários, de integração e de ponta-a-ponta, pois não vejo um substituindo o outro, mas se somando entre si 🤝