TypeScript é um superconjunto do JavaScript que adiciona tipagem estática e outros recursos ao ecossistema. Ele foi criado pela Microsoft em 2012, sob a liderança de Anders Hejlsberg (também criador do C#), com o objetivo de facilitar o desenvolvimento de aplicações em grande escala. Ao longo desta aula, vamos explorar o motivo pelo qual o TypeScript se tornou tão popular, como ele resolve problemas comuns do JavaScript e como você pode começar a usá-lo hoje mesmo.

Se você já escreveu código JavaScript por um tempo, provavelmente já sentiu a frustração de erros em tempo de execução que poderiam ser evitados. TypeScript entra nesse cenário como uma camada de segurança que detecta muitos problemas antes mesmo de o código ser executado. Vamos mergulhar nos detalhes.

Tipagem estática

O JavaScript é uma linguagem de tipagem dinâmica, o que significa que as variáveis podem receber valores de qualquer tipo sem restrições, e o tipo pode mudar durante a execução. Isso oferece flexibilidade, mas também é fonte de muitos erros sutis. Por exemplo, você pode esperar que uma função receba um número, mas passar uma string, e o JavaScript tentará fazer uma coerção implícita, muitas vezes gerando resultados inesperados.

TypeScript introduz a tipagem estática opcional, permitindo que você defina explicitamente os tipos de variáveis, parâmetros, retornos de função e propriedades de objetos. Isso não só documenta o código, mas também permite que o compilador verifique se os tipos estão corretos em tempo de desenvolvimento. Se você tentar atribuir um valor de tipo incompatível, receberá um erro na hora, evitando que o problema chegue aos usuários.

Exemplo simples em JavaScript:

function soma(a, b) {
  return a + b;
}

console.log(soma(1, "2")); // "12" (concatenação, não soma)

Em TypeScript, você pode anotar os tipos:

function soma(a: number, b: number): number {
  return a + b;
}

// Erro de compilação: Argument of type 'string' is not assignable to parameter of type 'number'.
// console.log(soma(1, "2"));
console.log(soma(1, 2)); // 3

Além de tipos primitivos, o TypeScript suporta tipos complexos como arrays, objetos, uniões, interseções, genéricos, etc. Isso permite modelar dados com precisão e capturar muitos bugs antes da execução.

O que resolve

O TypeScript resolve uma série de problemas comuns no desenvolvimento JavaScript, especialmente em projetos de médio e grande porte. Aqui estão os principais:

  • Erros em tempo de execução: Muitos erros que só apareceriam quando o código fosse executado (como chamar uma função com argumentos incorretos ou acessar propriedades inexistentes) são detectados em tempo de compilação.
  • Dificuldade de refatoração: Em JavaScript, renomear uma função ou alterar a estrutura de um objeto pode quebrar o código em vários lugares sem que você perceba. Com o TypeScript, o compilador aponta exatamente onde você precisa ajustar.
  • Falta de autocompletar e IntelliSense: Editores como VS Code usam os tipos do TypeScript para oferecer sugestões de código, autocompletar e documentação inline, aumentando a produtividade.
  • Comunicação entre equipes: Os tipos funcionam como uma forma de documentação viva, deixando claro o que cada função espera e retorna, facilitando o trabalho em equipe e a manutenção.
  • Escalabilidade: Projetos grandes tendem a ficar caóticos em JavaScript puro. O TypeScript impõe uma estrutura que ajuda a manter a consistência e a evitar erros.

Além disso, o TypeScript é compilado para JavaScript, então você pode usá-lo em qualquer ambiente onde o JavaScript roda, como navegadores, Node.js, Deno, etc.

Como se relaciona com JS

TypeScript é um superconjunto do JavaScript: todo código JavaScript válido é também TypeScript válido. Isso significa que você pode renomear um arquivo .js para .ts e começar a adicionar tipos gradualmente, sem precisar reescrever tudo de uma vez. Essa característica é fundamental para a adoção em projetos existentes.

O TypeScript não é executado diretamente no navegador ou no Node.js; ele precisa ser compilado (transpilado) para JavaScript. O compilador (tsc) remove as anotações de tipo e gera código JavaScript limpo, que pode ser executado em qualquer ambiente. O processo de compilação também pode realizar outras transformações, como converter recursos modernos do ECMAScript para versões mais antigas, se necessário.

Exemplo de código TypeScript:

interface Pessoa {
  nome: string;
  idade: number;
}

function saudacao(pessoa: Pessoa): string {
  return `Olá, ${pessoa.nome}!`;
}

const pessoa: Pessoa = { nome: "Maria", idade: 30 };
console.log(saudacao(pessoa));

Após a compilação, o JavaScript gerado será algo como:

function saudacao(pessoa) {
  return `Olá, ${pessoa.nome}!`;
}

const pessoa = { nome: "Maria", idade: 30 };
console.log(saudacao(pessoa));

Note que as anotações de tipo e a interface foram removidas. Isso mostra que o TypeScript é apenas uma ferramenta de desenvolvimento; em tempo de execução, o código é JavaScript puro.

Além disso, o TypeScript acompanha as novas versões do ECMAScript, permitindo que você use recursos futuros antes de serem amplamente suportados, pois o compilador pode transpilá-los para versões mais antigas.

Primeiros passos

Para começar a usar TypeScript, você precisa instalá-lo em seu ambiente. O pré-requisito é ter o Node.js instalado. Você pode instalar o TypeScript globalmente ou localmente no projeto. A forma mais comum é instalar localmente como dependência de desenvolvimento.

Passos:

  1. Inicialize um projeto Node.js (se ainda não tiver): npm init -y.
  2. Instale o TypeScript: npm install --save-dev typescript.
  3. Crie um arquivo de configuração tsconfig.json. Você pode gerar um com npx tsc --init, que cria um arquivo com várias opções comentadas.
  4. Crie um arquivo .ts, por exemplo index.ts.
  5. Compile o arquivo com npx tsc index.ts (ou npx tsc se houver tsconfig). Isso gerará um arquivo index.js.
  6. Execute o JavaScript gerado com node index.js.

Exemplo de um arquivo TypeScript simples (index.ts):

function cumprimentar(nome: string): string {
  return `Olá, ${nome}!`;
}

const mensagem = cumprimentar("Mundo");
console.log(mensagem);

Para facilitar o desenvolvimento, você pode usar o modo watch (tsc --watch) para recompilar automaticamente a cada alteração. Além disso, editores como VS Code têm suporte nativo a TypeScript, fornecendo feedback imediato de erros e IntelliSense.

Uma dica importante: comece aos poucos. Você pode usar a opção allowJs no tsconfig para permitir arquivos JavaScript no projeto e ir convertendo gradualmente.

Boas práticas e observações finais

Algumas boas práticas ao adotar TypeScript:

  • Configure o strict: true no tsconfig para obter o máximo de verificação de tipos.
  • Use tipos explícitos em funções e variáveis, mas deixe o TypeScript inferir quando não for necessário.
  • Aproveite recursos como interfaces, tipos utilitários e enums para modelar seus dados.
  • Integre a verificação de tipos ao seu pipeline de CI para evitar que erros cheguem à produção.
  • Mantenha as dependências de tipo (@types) atualizadas para bibliotecas sem tipos nativos.

Lembre-se: TypeScript não substitui JavaScript, ele o aprimora. A curva de aprendizado é suave e os benefícios são enormes, especialmente em projetos sérios.

Referências

Exercícios

  1. Crie um arquivo TypeScript chamado exercicio1.ts que declare uma variável idade com tipo number e uma variável nome com tipo string. Atribua valores e imprima no console.

✓ Resposta:
const nome: string = "Maria";
const idade: number = 30;
console.log(`Nome: ${nome}, Idade: ${idade}`);
  • Escreva uma função em TypeScript que receba dois números e retorne a soma. Teste com valores corretos e veja o erro ao passar uma string.
  • ✓ Resposta:
    function somar(a: number, b: number): number {
      return a + b;
    }
    console.log(somar(2, 3)); // 5
    // console.log(somar(2, "3")); // erro de compilação
    
  • Crie uma interface Carro com propriedades marca (string), ano (number) e opcional (boolean). Crie um objeto que siga essa interface.
  • ✓ Resposta:
    interface Carro {
      marca: string;
      ano: number;
      opcional?: boolean;
    }
    
    const meuCarro: Carro = {
      marca: "Toyota",
      ano: 2020
    };
    console.log(meuCarro);
    
  • Explique por que o TypeScript é considerado um superconjunto do JavaScript e dê um exemplo de código que é válido em ambos.
  • ✓ Resposta: TypeScript é um superconjunto porque todo código JavaScript é válido em TypeScript, mas nem todo TypeScript é JavaScript. Exemplo: let x = 10; é válido em ambos. Adicionar tipos como let x: number = 10; é TypeScript.
  • Configure um projeto TypeScript do zero: crie um diretório, inicialize o npm, instale o TypeScript, crie um tsconfig e compile um arquivo simples.
  • ✓ Resposta: Comandos: mkdir meu-projeto; cd meu-projeto; npm init -y; npm install --save-dev typescript; npx tsc --init; criar index.ts com código simples; npx tsc; node index.js.