Entendendo e configurando um projeto TypeScript
Como consta na documentação oficial, o TypeScript é um superset do JavaScript, ou para facilitar o entendimento, podemos dizer que o JavaScript está contido no TypeScript, ou seja, é um subconjunto do TypeScript. Então todo código JavaScript é válido em TypeScript, mas o inverso não é verdadeiro.
TypeScript is a language that is a superset of JavaScript: JS syntax is therefore legal TS.
Neste texto, pretendo compartilhar um pouco sobre as razões por trás do uso do TypeScript e, além disso, explicar como configurar um projeto do zero usando os pacotes TypeScript, ts-node e nodemon.
Breve introdução ao TypeScript
O TypeScript foi anunciado pela Microsoft em outubro de 2012, liderado por Anders Hejlsberg, criador do C# e Turbo Pascal. Surgiu para superar as limitações do JavaScript em aplicações de grande escala, oferecendo tipagem estática e recursos de programação orientada a objetos. Isso visava reduzir erros em tempo de execução devido à falta de verificação de tipos no JavaScript, tornando mais fácil para os desenvolvedores construir e manter aplicações complexas.
Para ilustrar, abaixo está um pequeno exemplo de código em TypeScript:
function multiply(a: number, b: number): number {
return a * b;
}
Se você copiar e colar este código no console do seu DevTools, vai pegar o seguinte erro:
SyntaxError: Unexpected token ':'. Expected a ')' or a ',' after a parameter declaration.
O motivo do erro é simples, os navegadores não sabem como lidar com um código TypeScript. O mesmo vale para o Node.js. Portanto, para executar este código, precisamos antes, transformá-lo em um código JavaScript em um processo chamado de transpilação (transpiling).
Pegando o primeiro exemplo, mais acima, o resultado é um código JavaScript, que agora pode ser executado em um navegador ou Node.js, veja a seguir:
function multiply(a, b) {
return a * b;
}
Além de ser fortemente tipado, ou seja, precisamos especificar o tipo de cada variável/propriedade/retorno, o TypeScript oferece um mecanismo de verificação com base na tipagem. Por exemplo, considerando o código abaixo, durante o processo de compilação com o tsc, a CLI do TypeScript, seria gerado o seguinte erro:
Argument of type 'string' is not assignable to parameter of type 'number'
function multiply(a: number, b: number): number {
return a * b;
}
console.log(multiply(5, 10));
console.log(multiply('5', 10));
O erro deve-se ao fato de que o parâmetro "a" é do tipo number. Porém, a última linha de código passa o valor '5'
que é uma string para o parâmetro.
Além das vantagens que já foram citadas, podemos destacar:
- Compatibilidade com diversas versões do JavaScript: O TypeScript permite configurar a geração de código JavaScript em uma versão específica, tornando-se útil quando precisamos gerar código em versões mais antigas, como o ES5.
- Melhoria na legibilidade do código: Graças ao uso de tipos, interfaces, classes e outras funcionalidades, o TypeScript possibilita escrever código mais claro e compreensível. Isso organiza o código de maneira mais intuitiva, facilitando sua compreensão.
- Facilidade de refatoração: No ambiente de desenvolvimento, como o VS Code, é possível realizar refatorações com facilidade. Por exemplo, ao clicar em uma propriedade e pressionar a tecla F2 para renomeá-la, o novo nome é propagado de forma automática ao longo do código que faz uso dessa propriedade. Isso aumenta a produtividade e reduz a probabilidade de erros durante a refatoração.
Agora vamos explorar como configurar um projeto do zero utilizando TypeScript.
Configurando um projeto TypeScript
Abaixo utilizei o seguinte comando para criar o projeto:
# cria um diretório chamado "teste"
mkdir teste
# entra no diretório
cd teste
# inicializa o projeto npm
npm init -y
# Fornece declarações de tipos para o Node.js,
# o que permite que o editor de código compreenda
# as APIs e sugira automaticamente os nomes de
# funções, propriedades e outros elementos.
npm install @types/node --save-dev
# instala a dependência typescript
npm install typescript --save-dev
# cria o arquivo tsconfig.json
npx tsc --init
# retorno do comando acima:
Created a new tsconfig.json with:
TS
target: es2016
module: commonjs
strict: true
esModuleInterop: true
skipLibCheck: true
forceConsistentCasingInFileNames: true
Para testar vamos criar um arquivo chamado index.ts com o seguinte conteúdo:
Para converter o arquivo index.ts em um arquivo index.js, basta executar o comando npx tsc
. Colei o resultado logo abaixo:
Para executar: node index.js
Então sempre que precisarmos executar um código TypeScript, será necessário gerar o JavaScript e depois executá-lo. Considerando que ao longo do desenvolvimento vamos alterar o código diversas vezes, não seria muito produtivo executar estes dois comandos toda vez que quisermos testar algo. Para simplificar esse processo, podemos utilizar a biblioteca ts-node.
ts-node is a TypeScript execution engine and REPL for Node.js.
https://typestrong.org/ts-node/docs/
Configurando o ts-node
A biblioteca ts-node permite a execução simplificada de código TypeScript com apenas um comando, como por exemplo, ts-node index.ts
. Por trás dos panos, ela cuida do processo de transpilação e execução do código.
Para instalar a dependência:
npm install ts-node --save-dev
Agora podemos executar a aplicação com um único comando:
npx ts-node index.ts
Agora ficou um pouco mais fácil executar um código em TypeScript. No entanto, podemos aprimorar ainda mais o ambiente de desenvolvimento com a utilização da biblioteca nodemon.
Configurando o nodemon
Podemos utilizar a biblioteca nodemon para monitorar alterações em arquivos com a extensão ".ts". Então sempre que uma modificação é detectada, o nodemon reexecuta o comando npx ts-node index.ts
automaticamente.
npm install nodemon --save-dev
Cadastrando o script start:dev
no arquivo package.json:
Agora podemos simplesmente utilizar o comando npm run start:dev
para iniciar a aplicação e conforme modificarmos os arquivos com a extensão .ts
o nodemon irá chamar novamente o comando npx ts-node index.ts
. Isto ajuda bastante durante o desenvolvimento.
Até este ponto, utilizamos três bibliotecas: typescript, ts-node e nodemon. As duas últimas não são obrigatórias, mas são úteis.
Explorando o tsconfig.json
Logo no início da construção deste projeto, executamos o comando npx tsc --init
que criou um arquivo chamado tsconfig.json.
The presence of atsconfig.json
file in a directory indicates that the directory is the root of a TypeScript project. Thetsconfig.json
file specifies the root files and the compiler options required to compile the project.
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
Este arquivo permite que você especifique várias opções, como versão do ECMAScript, diretórios de saída, módulos a serem usados, configurações de tipo, entre outras.
Para ilustrar, vamos criar um novo arquivo chamado tsconfig.dev.json, alterar o tsconfig.json e o package.json:
No arquivo package.json vamos alterar para incluir os dois scripts:
Agora podemos executar os seguintes comandos:
# Para ambiente de desenvolvimento
npm run start:dev
# Para ambiente de produção (executar após o build)
npm run start:prod
# Para compilar
npm run build
Debugando o código no VS Code para Node.js
Por fim, vamos falar rapidamente sobre o debug. O processo para efetuar o debug no VS Code é bem simples:
- certifique-se de que os arquivos source maps estão sendo gerados. Essa opção está no tsconfig.json (
sourceMap: true
) - Adicione o breakpoint na linha desejada
- Pressione
ctrl + shift + p
(no maccmd + shift + p
) e digitedebug: debug npm script
. No nosso exemplo selecione a opçãonpm run start:dev
.
Considerações
Em resumo, o TypeScript é uma ferramenta poderosa que pode ajudar a escrever código JavaScript mais robusto, seguro e fácil de manter. No entanto, é importante considerar a curva de aprendizado e a necessidade de conhecimento da equipe antes de adotar o TypeScript em um projeto.
Particularmente, acredito que o TypeScript realmente contribui para a escrita de um código mais limpo e legível. No entanto, é essencial que a equipe possua conhecimento para aproveitar ao máximo essa solução.
Para não estender muito o texto, deixei para abordar no futuro um pouco sobre os source maps, arquivos *.d.ts e outros recursos.
Links interessantes:
- Trilha para estudar TypeScript: https://roadmap.sh/typescript
- Documentação oficial do TypeScript: https://www.typescriptlang.org/docs/
- Playground: https://www.typescriptlang.org/play