Gostaria de trazer um comentário sobre onde você diz "Usar typescript é escrever testes unitários enquanto escreve código.".


É interessante pensar que o TypeScript em si não vai verificar os tipos após a compilação, caso você não tenha feito isso usando o próprio JavaScript.

Então o "teste do TypeScript", muitas vezes consiste em garantir que a compilação está devidamente tipada antes de gerar o código compilado.


Por exemplo:

const sum = (a: number, b: number): number => a + b;
  • Durante o desenvolvimento (.ts): o método espera por números em todos os pontos (entrada e saída), alertando sempre que você tentar usar outro tipo.
  • Ao compilar (.js), o JavaScript aceita qualquer tipo nos parâmetros a e b, inclusive contatenando strings no resultado e retornando uma string ao invés de um número.

Tentei mostrar de uma forma bem simples, mas isso poderia inclusive trazer vulnerabilidades ao confiar que o TypeScript seria "teste" o suficiente para cobrir métodos unitários, especialmente pois normalmente a produção irá com todos os arquivos compilados para .js 🙋🏻‍♂️

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: ```ts 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` e `b`. > > 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 🤝