Alura > Cursos de Programação > Cursos de Node.JS > Conteúdos de Node.JS > Primeiras aulas do curso Typescript: construção de uma API com tipagem segura

Typescript: construção de uma API com tipagem segura

Transformando um arquivo JS em TS - Apresentação

Olá! Te desejo as boas-vindas ao curso de TypeScript! Meu nome é Emerson Laranja, sou membro do time de conteúdo da Alura e serei seu instrutor nesta jornada.

Audiodescrição: Emerson se descreve como um homem negro, com barba e cabelos curtos e escuros. Usa óculos quadrados e veste uma camiseta lisa na cor azul. Ao fundo, uma parede branca iluminada em tons de verde e azul.

Este conteúdo é voltado para pessoas que já concluíram a formação em JavaScript e possuem familiaridade com a linguagem. Aqui, daremos nossos primeiros passos com o TypeScript.

Neste curso, você aprenderá como converter um arquivo JavaScript para TypeScript. Além disso, será apresentado a conceitos como anotações, estrutura de um projeto TypeScript, tipagem e criação de tipos personalizados, bem como várias outras estruturas, como enum, in, campos opcionais e como fazer filtros usando generics.

Todo esse aprendizado será aplicado ao nosso projeto chamado Adopet, que é uma plataforma de adoção de animais. Incentivo você a aproveitar todos os recursos da plataforma. Além dos vídeos e das atividades, você pode usar o fórum e o Discord da nossa comunidade para se aprofundar ainda mais em parceria com outras pessoas que também estão estudando.

Vamos nessa?

Transformando um arquivo JS em TS - O compilador TSC

Agora, vamos conhecer o nosso projeto, o Adopet. Com ele aberto no navegador, temos acesso a sua interface, onde há um botão rosa escrito "Ver pets disponíveis para adoção". Ao clicá-los, somos redirecionados para uma lista de animais, que chamamos de pets, e nosso trabalho será criar uma API no back-end que permita a pessoa adotante adotar esse pet, bem como também fazer gerência de um pet e a busca por ele.

Temos o código inicial no VS Code. No explorador, temos os arquivos iniciais que serão fornecidos para você, entre eles o package-lock.json, package.json, server.js, em que estamos utilizando o express e iniciando servidor na porta 3000, e app.js, que é nosso arquivo principal.

Neste último arquivo, temos duas rotas já feitas com o express. A primeira delas está na linha 8, com app.get(), onde a pessoa receberá a mensagem "Bem-vindo ao curso de TypeScript!" ao entrar em localhost 3000.

app.get("/", (_, res) => {
  res.send("Bem vindo ao curso de TypeScript!");
});

Mais abaixo, na linha 28, temos app.post() onde criamos dois pets ao acessar localhost 3000/pets. Chamamos a função criaPet(), passando como primeiro parâmetro uma função responsável por gerar o id, o nome do pet, a espécie dele, a idade e se ele foi adotado ou não, que por padrão está como false.

app.post("/pets", (_, res) => {
  const pet1 = criaPet(geraId(), "Bolt", "cachorro", 3, false);
  const pet2 = criaPet(geraId(), "Mel", "gato", 2, false);

  res.send([pet1, pet2]);
});

Vamos analisar essa função criaPet():

function criaPet(id, nome, especie, idade, adotado) {
  return {
      id,
      nome,
      especie,
      idade,
      adotado,
  };
}

O que ela faz é basicamente receber os parâmetros e retorná-los como um objeto. Além disso, na nossa função geraId(), temos um id iniciado como 0, e à medida que vamos criando um pet, esse id vai sendo incrementado.

let id = "0";
function geraId() {
  id = id + 1;
  return id;
}

Após o app.post(), na linha 28, temos o res.send, na linha 32, enviando os dois pets criados, tanto o cachorro Bolt quanto a gata Mel. Podemos testar utilizando o Insomnia.

O Insomnia é um software que permite fazermos requisições HTTP. Pode ser usado tanto o Insomnia como o Postman. Disponibilizaremos para você cada uma dessas rotas que usaremos ao longo do curso.

Inicialmente, vamos usar essa rota fora da pasta pets, que é a Cria Pet, onde estamos acessando o localhost 3000. Mas antes, de fato, de enviar a requisição, temos que inicializar nosso servidor. Para isso, abrimos o terminal e executamos o comando node .\server.js para iniciar a execução.

node .\server.js

Recebemos o servidor executando o localhost 3000.

Retomando ao Insomnia e enviando a requisição, temos criado os nossos animais: o cãro Bolt e a gata Mel. Porém, algo um pouco estranho ocorreu. No cão Bolt, temos o id como sendo 01, já na gata Mel o id está como 011. A ideia é que esse id seja incremental, ou seja, Bolt teria o id 01 e Mel o id 02. Vamos voltar ao VS Code e ver o que está acontecendo.

No arquivo app.js, na linha 20, note que nosso id está entre aspas:

let id = "0";
function geraId() {
  id = id + 1;
  return id;
}

Ou seja, cabamos por declarar o id como uma string. Então, ao fazer essa soma de uma string com 1, estamos concatenando, juntando os valores que estamos recebendo. Logo, 0 com 1, fica 01, quando recebemos outra chamada, torna-se 011, e assim por diante. Dessa forma, um erro que fizemos durante a construção do nosso código, só foi identificado em tempo de execução. E é aí que o TypeScript consegue nos auxiliar, antecipando essa visualização do erro enquanto estamos digitando nosso código.

Para observarmos isso, temos que fazer as modificações necessárias para usar o TypeScript. A primeira delas é abrir nosso menu explorador no VS Code e dizer para nosso compilador quais são os arquivos TypeScript. Para isso, temos que renomear todos nossos arquivos com extensão .js para .ts. Logo, app.js passará a ser app.ts, e server.js passará a ser server.ts.

Agora, precisamos passar pelo processo de compilação do TypeScript. Para isso, vamos parar a execução do servidor, abrir o terminal e executar o comando npx tsc, que é o compilador do TypeScript, informando quais arquivos queremos compilar. No caso, server.ts e app.ts:

npx tsc .\server.ts .\src\app.ts

Vamos aguardar alguns instantes até o processo de compilação finalizar.

Finalizado nosso processo de compilação, não recebemos nada, o que indica que não aconteceu nenhum erro. Então, vamos fechar o terminal e abrir o menu explorador do VS Code novamente.

Note que surgiram novamente os arquivos app.js e server.js. Ao abrir o app.js, percebemos que existe o que criamos anteriormente, como as funções criaPet() e geraId(), porém com uma escrita um pouco diferente. O que acontece é que o TypeScript transforma nosso código em uma versão um pouco mais antiga do JavaScript que consiga ser executada nos nossos servidores Node e navegadores, visto que o TypeScript não é entendido pelos navegadores.

Além disso, se retomarmos o menu explorador, veremos que nosso arquivo app.ts ficou vermelho. Ao abri-lo, notamos que ele possui alguns sublinhados vermelhos em partes do código. Isso indica que há algum erro nesses trechos. Na sequência, veremos como resolver!

Transformando um arquivo JS em TS - Evitando erros com TypeScript rigoroso

Até agora, você aprendeu sobre o processo de compilação por meio do compilador do TypeScript, o TSC. Durante esse processo de compilação, foram gerados alguns arquivos JavaScript e, em nossos arquivos TypeScript, encontramos alguns sublinhados vermelhos em partes do nosso código. Chamamos esses sublinhados de anotações, e elas indicam erros ou partes do código que estão faltando.

Por exemplo, no arquivo app.ts, se colocarmos o cursor na linha 6, no parâmetro res, recebemos a mensagem de que este parâmetro possui um tipo implícito any. Assim como conseguimos declarar os tipos number para números, string para textos e boolean para indicar se uma variável possui um valor verdadeiro ou falso, também temos o tipo any, utilizado quando não sabemos qual é o tipo ou o valor que vamos atribuir.

No entanto, não é considerada uma boa prática permitir que o TypeScript infira os tipos, atribuindo-os como any, pois assim não conseguimos prever erros de tipos. O ideal é que nós mesmos declaremos o tipo de cada uma das variáveis.

Por exemplo, na linha 6, res é um tipo Response do express. Para declararmos isso, inserimos dois pontos e passamos Response:

app.get("/", (_, res: Response) => {
  res.send("Bem vindo ao curso de TypeScript!");
});

Ao passar o cursor por cima, percebemos que esse Response específico trata-se de uma interface genérica, e não o Response do express. Isso se relacionado com o erro que temos na linha 1, na importação do express, que, resumidamente, indica que precisamos instalar a biblioteca @types/express.

O que acontece é que, embora tenhamos instalado o express, que é um conjunto de funcionalidades, ainda precisamos instalar @types para podermos declarar o tipo de cada uma dessas funcionalidades.

A biblioteca @types é comum a muitas outras bibliotecas. Para instalar, vamos copiar o comando npm i --save-dev @types/express e executá-lo no terminal:

npm i --save-dev @types/express

Feito isso, basta aguardar até que a biblioteca seja instalada.

Após instalarmos a biblioteca e fecharmos o terminal, notamos que agora possuímos os tipos do express. Na linha 4, ao pressionar enter e digitarmos app., o próprio VS Code, que possui uma boa integração com o TypeScript, nos mostra todos os métodos disponíveis em nosso app.

O mesmo podemos fazer ao declarar app.get, tipando o parâmetro res. Para isso, digitamos res: e, em seguida, digitamos novamente Response, agora selecionando a opção Response do express.

app.get("/", (_, res: Response) => {
  res.send("Bem vindo ao curso de TypeScript!");
});

Podemos fazer o mesmo com a nossa função criaPet(). Recebemos diversos parâmetros, como id, que será um number, nome e especie, que serão string, idade que também será um number, e adotado, que será um boolean indicando se o animal já foi adotado ou não.

function criaPet(
  id: number,
  nome: string,
  especie: string,
  idade: number,
  adotado: boolean
) {
  return {
    id,
    nome,
    especie,
    idade,
    adotado,
  };
}

Após o processo de compilação, recebemos um erro relacionado à importação que estamos utilizando. Além disso, ao abrir nosso menu explorar, percebemos que nossos arquivos JavaScript e TypeScript estão misturados, o que não é o ideal. Queremos modificar apenas o arquivo TypeScript e manter os arquivos JavaScript separados apenas para build, para evitar alterações indesejadas.

Para resolver isso, precisamos configurar nosso compilador para que ele se comporte dessa forma, criando uma pasta separada. Faremos isso alterando o arquivo de configurações do nosso compilador, tsconfig.json.

Neste arquivo, podemos inserir várias regras. Algumas delas você já deve ter percebido, como o sublinhado vermelho que indica a regra do noImplicitAny, que não permite que o código seja compilado caso possua alguma variável implícita como any.

Para resolver nosso problema, precisamos adicionar algumas linhas a este código. A primeira delas é o nosso diretório de saída, onde ficarão os arquivos JavaScript compilados. Para isso, na linha 6, incluímos "outDir": e, em seguida, ./build.

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "noImplicitAny": true,
    "outDir": "./build",
    "noEmitOnError": true
  },
  "include": ["./src/**/*", "./server.ts"]
}

Agora, podemos excluir nossos arquivos JavaScript, pois faremos o processo de compilação novamente. Perceba que nosso arquivo tsconfig.json, na linha 9, possui o campo include, que mapeia os arquivos que serão compilados. Neste caso, todos os arquivos que estão dentro de src e o nosso arquivo server.ts. Com essa configuração, fica muito mais simples executar o nosso processo de compilação.

Portanto, vamos abrir o terminal, limpar com o comando clear e executar o comando npx tsc:

npx tsc

Com isso, todos os nossos arquivos .ts serão compilados em .js. Vamos aguardar até que o processo seja finalizado.

Uma vez finalizado, se não recebermos nenhuma mensagem, significa que não tivemos nenhum erro. Agora, podemos testar nosso código executando o servidor.

Porém, antes disso, vale ressaltar que o processo de compilação, execução do servidor, parada do servidor e recompilação podem ser um pouco cansativos. Para facilitar, em nosso arquivo package.json, adicionamos um script na linha 8, que usa a biblioteca tsc-watch:

"start": "tsc-watch --onSuccess \"node build/server.js\""

Dessa forma, sempre que modificarmos nosso código em TypeScript, a recompilação será feita automaticamente enquanto nosso servidor continua executando. Isso evita a necessidade de parar e reiniciar o servidor constantemente.

Para isso, basta abrir o terminal, executar o comando npm start e aguardar até que a inicialização seja concluída.

npm start

Recebemos a mensagem de que nosso servidor está sendo executando e, agora, podemos verificar se ele realmente está funcionando por meio de uma requisição no Insomnia.

Com o Insomnia aberto, temos a requisição Cria Pet, apontando para localhost:3000/pets. Clicando no botão "Send", recebemos como resposta os nossos dois animais criados: Bolt, o cachorro, e Mel, a gata. Dessa forma, conseguimos fazer a criação usando o TypeScript, que nos auxilia com as tipagens.

No entanto, nosso código está chumbado, ou seja, as informações estão estáticas e todos os dados para criar um pet estão sendo descritos diretamente no código. A ideia é que nós recebamos essas informações do usuário e retornemos o pet criado. É o que veremos na sequência!

Sobre o curso Typescript: construção de uma API com tipagem segura

O curso Typescript: construção de uma API com tipagem segura possui 141 minutos de vídeos, em um total de 56 atividades. Gostou? Conheça nossos outros cursos de Node.JS em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Node.JS acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas