Como usar TypeScript com Node.js – Parte 3

Nesta série de artigos estamos explorando o uso do TypeScript, inicialmente fazendo alguns testes básicos e mais pro fim da segunda parte, iniciamos a construção de uma WebAPI com Express e TypeScript, sendo que apenas deixamos tudo configurado.

É nesta terceira parte que vamos de fato usar TypeScript com Express para construção de uma WebAPI de exemplo.

Atenção: este é um post intermediário, para alguém que já tem conhecimentos básicos em Node.js. Ele já vai direto ao ponto, para quem precisa de algo com mais didática, recomendo começar com esse.

#1 – Routes com TypeScript

Crie uma pasta routes no seu projeto Express e cria uma index.ts dentro dela, com o seguinte código.

Aqui estamos usando a sintaxe mais moderna para JavaScript, com import para dependências e export para exportação de objetos. Também usamos decomposição na importação, pois só precisamos da função Router do pacote Express.

De resto, é uma rota bem simples, como já fizemos anteriormente.

Lá no nosso app.ts, vamos modificar também, para usarmos este arquivo de rotas.

Do jeito que está, esta rota já funciona, mas não faz nada que preste.

Então vamos adicionar uns models tipados na nossa api.

#2 – Models com TypeScript

Crie uma pasta models no seu projeto e dentro crie um arquivo customer.ts, que definirá o tipo de dado Customer da nossa web API.

Agora, para usar esse novo tipo que criamos, vamos importá-lo no nosso arquivo de rotas.

Note que usei o novo tipo importado para criarmos um array in-memory fortemente tipado, como o TS strict nos manda fazer e estamos retornando o mesmo em nossa rota GET /.

Mas e se quisermos criar uma rota para salvar novos customers?

Aqui, declaramos uma constante newCustomer que é do tipo Customer, o que obriga o preenchimento dos seus 3 campos, que obteremos no corpo da requisição, afinal é um POST /.

Para que o body da requisição seja corretamente interpretado pelo Express, precisamos voltar ao nosso app.ts e usar a dependência do body-parser que instalamos lá atrás mas ainda não tínhamos utilizado.

Basta importar a dependência e depois registrá-la como um middleware no Express, antes da rota.

Caso você queira adicionar o suporte a TS na biblioteca body-parser também, você pode instalar o @types dela, como já fizemos para outras dependências antes.

Sempre em ambiente de desenvolvimento!

#3 – Typecasting com Express

Você deve ter notado que o req.body e os req.params do Express não estão tipados, o que mantém a possibilidade de falhas na codificação.

Assim como fizemos anteriormente, podemos utilizar typecasting para converter objetos dinâmicos como o body e o params em tipos estáticos definidos por nós. Sim, por nós, porque não tem como existir um pacote @types para todas as possibilidades que você pode inventar na sua web API né…

No exemplo abaixo, criei um tipo para o body da requisição da nossa rota, o que pode ser útil para POST, PUT e PATCH, dependendo de como você está estruturando sua web API.

Novamente, tome cuidado com typecasting pois ele não faz milagre.

Curso Node.js e MongoDB
Curso Node.js e MongoDB

#4 – Compilando

Uma coisa que pode estar incomodando você é que você vai estar o tempo todo programando em arquivos TS e compilando eles em JS, criando não apenas o trabalho de compilação, mas também a bagunça de arquivos praticamente duplicados por todo o projeto, certo?

Aqui vão duas boas práticas de compilação.

A primeira é abrir o seu tsconfig e alterar o diretório padrão onde os arquivos compilados serão armazenados.

A sugestão acima é que os arquivos JS sejam compilados e armazenados em uma pasta dist na raiz do projeto.

Agora, para compilar tudo que programamos nessa Web API e ver se essa config surtiu efeito, apenas navegue até a raiz do projeto e rode o comando tsc nela, sem nenhum parâmetro adicional.

Isso irá compilar todos os arquivos TS do seu projeto e colocar os equivalentes JS, com a mesma estrutura de pastas original, dentro da pasta dist.

É essa pasta dist que contém a sua aplicação compilada em JS e pronta para execução. Recomendo que coloque ela no seu .gitignore porque não há necessidade de ter ela versionada, pois toda vez que rodar tsc ela será atualizada.

E por fim, também recomendo que configure o script de start corretamente no seu packages.json.

Assim, para executar nosso projeto, bastará escrever npm start na raiz do projeto e ele vai se achar corretamente.

Outra dica comum de organização é, assim como criamos uma pasta dist para os arquivos compilados em JS, crie uma pasta src para guardar os fontes TS do projeto, mantendo na raiz do projeto somente os arquivos de configuração e a pasta node_modules, como na imagem.

Para que o compilador do TS não se perca, isso exige que você edite outra configuração no tsconfig.json, como abaixo.

A rootDir define o diretório raiz dos seus fontes em TS, necessária para o compilador se achar na hora que você mandar o comando tsc na raiz do projeto.

Recomendo agora que execute esta aplicação e realize os testes.

#5 – Autocompilação

Você deve imaginar que mesmo com o comando tsc na raiz do projeto compilando tudo, é bem chato ter de ficar chamando este comando entre uma alteração e outra antes de reexecutar sua aplicação, certo?

Uma estratégia bem simples que você pode adotar é a de alterar o seu script de start no packages.json para executar o tsc antes do node, como abaixo.

Assim, toda vez que você rodar um npm start, ele primeiro vai executar o tsc e depois a aplicação Node transpilada.

Mas isso ainda exige que você tenha de derrubar a sua aplicação e reexecutá-la a cada alteração. Como podemos melhorar isso?

Uma estratégia bem comum entre programadores Node.js é o uso de nodemon, um pacote muito popular que sobe a sua aplicação e fica observando alterações nos arquivos para reexecutá-la automaticamente. Eu já falei dele neste vídeo abaixo, que recomendo que assista caso nunca tenha usado nodemon antes.

O que nem todo mundo sabe é que você pode configurar um arquivo nodemon.json para que diga a ele observar arquivos .TS da sua aplicação e a rodá-la com um comando definido por você, que inclua a transpilação, como abaixo.

Note que coloquei a pasta dist na configuração de ignore para que o nodemon não entre em loop. Outra alteração que fiz foi na configuração ext que lista as extensões que serão observadas pelo nodemon e que irão disparar a transpilação e reexecução.

Use esta web API como exemplo para avançar ainda mais nos seus estudos de TypeScript com Node.js.

Um abraço e sucesso.

Quer aprender desenvolvimento web fullstack usando JS e TS? Conheça o meu curso clicando no banner abaixo!

Curso FullStack
Curso FullStack

Publicado por

Luiz Duarte

Pós-graduado em computação, professor, empreendedor, autor, Agile Coach e programador nas horas vagas.