Alura > Cursos de Front-end > Cursos de JavaScript & TypeScript > Conteúdos de JavaScript & TypeScript > Primeiras aulas do curso Typescript: aplicando tipagem e princípios SOLID

Typescript: aplicando tipagem e princípios SOLID

O salto do JavaScript para o TypeScript - Apresentação

Apresentando o instrutor e o curso

Olá! Meu nome é João Vitor Veronese Vieira, e serei o instrutor deste curso de Fundamentos do TypeScript.

Audiodescrição: João é um homem branco, com olhos e cabelo castanhos. Ele veste uma camiseta preta e está em um estúdio iluminado pela cor azul.

Gostaríamos de dar as boas-vindas ao nosso curso de Fundamentos do TypeScript e nos apresentar brevemente. João Vitor Veronese Vieira é o criador do canal Manual do Front no YouTube. Ele é gaúcho, formado em Ciência da Computação, atualmente cursa pós-graduação em Front-End Engineering e possui mais de 10 anos de experiência na área. Atualmente, trabalha para uma startup dos Estados Unidos como Front-End Engineer.

Introduzindo a aplicação Buscante

Neste curso, utilizaremos a aplicação chamada Buscante, que é uma lista de livros na qual podemos buscar livros. Caso não encontremos nada, podemos mostrar uma mensagem para a pessoa usuária. Também podemos destacar livros que gostaríamos que a pessoa usuária prestasse mais atenção ou olhasse com carinho, pois são os livros que consideramos melhores, por exemplo.

Para implementar essa funcionalidade de destaque, vamos criar um método chamado onHighlightBook. Este método será responsável por destacar um livro específico. Vamos ver como ele é implementado:

onHighlightBook(book: Book) {
    const highlightedData: HighlightedBook | null = this.bookHighlighter.highlight(book);

    if (!highlightedData) {
        return;
    }

    this.highlightedBook.set(highlightedData);
}

Esse método utiliza um serviço chamado bookHighlighter para tentar destacar o livro. Se o livro puder ser destacado, ele é armazenado em highlightedBook.

Implementando funcionalidades de destaque e ordenação

Além disso, também precisamos de um método para remover o destaque de um livro, caso o usuário decida fechar o destaque. Para isso, utilizamos o método onCloseHighlight:

onCloseHighlight(): void {
    this.highlightedBook.set(null);
}

Nós também podemos ordenar nossos livros por título em ordem crescente e decrescente, e por autor em ordem crescente e decrescente. Tudo isso é o contexto perfeito para que tenhamos esse primeiro contato com o TypeScript. O TypeScript é um superset (superconjunto) de JavaScript e, nos dias atuais, é uma ferramenta obrigatória para construirmos sistemas mais robustos, onde podemos tipar corretamente e garantir que a comunicação entre componentes pais e filhos nos nossos frameworks front-end funcione corretamente. Dessa forma, criamos sistemas mais escaláveis e robustos, como o que vamos aprender neste curso.

Configurando o aplicativo com AppConfig

Ao olharmos rapidamente tudo o que temos preparado, aprenderemos a criar componentes que se comunicam entre si utilizando interfaces, diversos serviços como os de filtro, os de destacar um livro, e também realizar essa ordenação. Tudo isso será separado no AppConfig, que será nosso gerenciador, o orquestrador do nosso aplicativo de busca.

Para configurar nosso aplicativo, utilizamos o AppConfig. Vamos ver como configuramos os provedores necessários para o funcionamento do nosso aplicativo:

import { ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { BOOK_HIGHLIGHTER_TOKEN } from './tokens/book-highlighter.token';
import { routes } from './app.routes';
import { DefaultBookHighlighter } from './services/highlighter/default-book-highlighter.service';

export const appConfig: ApplicationConfig = {
  providers: [
    provideBrowserGlobalErrorListeners(),
    provideZonelessChangeDetection(),
    provideRouter(routes),
    {
      provide: BOOK_HIGHLIGHTER_TOKEN,
      useClass: DefaultBookHighlighter,
    }
  ]
};

Este trecho de código configura o AppConfig com os provedores necessários, incluindo o roteador e o serviço de destaque de livros.

Explorando as vantagens do TypeScript e princípios SOLID

Este será nosso primeiro contato com o TypeScript em um framework front-end muito utilizado atualmente. Vamos entender melhor todas as vantagens que essa ferramenta traz no nosso dia a dia como pessoas desenvolvedoras. Além de aprender sobre tudo isso, conheceremos o princípio do SOLID, que é uma filosofia, um conceito que nos ajuda a escrever um código ainda melhor e nos tornará pessoas desenvolvedoras ainda mais preparadas para o mercado de trabalho.

Portanto, venham com energia e curiosidade, pois estamos esperando no próximo vídeo.

O salto do JavaScript para o TypeScript - A dor do JavaScript e a solução TypeScript

Refletindo sobre desafios em projetos JavaScript

Olá, pessoas desenvolvedoras. Sejam bem-vindas ao primeiro vídeo da Aula 1. Temos uma pergunta para refletir: em algum momento, já trabalhamos em um projeto onde fizemos alterações e ficamos receosos de que isso pudesse quebrar outra parte do código, que não tinha relação direta com a mudança? Vamos usar o JavaScript como exemplo, pois essa é uma realidade comum. O JavaScript é extremamente flexível, e essa flexibilidade, especialmente em projetos grandes, pode gerar o receio de modificar algo indevido, talvez quebrando uma dependência desconhecida e criando bugs dispendiosos.

O desafio que enfrentamos é: como podemos ter certeza de que o código que estamos escrevendo está correto antes mesmo de rodá-lo no navegador, no caso de projetos front-end, por exemplo? Como garantir que uma função, como a que deixamos pronta para somar dois números, sempre receba números e não uma combinação de número e string?

Demonstrando problemas de tipagem no JavaScript

Vamos demonstrar isso. Primeiro, vamos criar uma função simples em JavaScript para somar dois números:

function soma(number1, number2){
    return number1 + number2;
}

Agora, vamos fazer algumas chamadas a essa função e exibir os resultados:

// Chamadas
const resultado1 = soma(1, 2);
const resultado2 = soma(1, 2);

// Exibir
console.log(resultado1);
console.log(resultado2);

Se rodarmos nosso código utilizando Node, na pasta "exemplos", digitando node exemplos/video01.1.js, obteremos 3 e 3, pois estamos enviando exatamente os mesmos valores, 1 e 2.

node exemplos/video01.1.js

No entanto, se alterarmos o código, já que o JavaScript permite, e enviarmos uma string por engano, como uma pessoa desenvolvedora nova no projeto que desconhece a documentação, ao salvar, limpar o terminal e rodar o código novamente, o resultado será 12, 3 e 12. Vamos ver como isso acontece:

const resultado2 = soma(1, "2");

E então, rodamos novamente o código:

node exemplos/video01.1.js

Podemos nos perguntar: como isso é possível? Isso ocorre porque o JavaScript não "reclama"; ele tenta adivinhar e nos ajudar, mas essa adivinhação nem sempre é benéfica, sendo uma fonte comum de bugs que descobrimos tarde demais. Sem testes unitários, por exemplo, poderíamos deixar isso passar para a produção, pois não geraria erro. Não compilamos código JavaScript, apenas o transpomos, e talvez só perceberíamos o problema quando os usuários da aplicação encontrassem o erro e reportassem ao suporte.

Introduzindo o TypeScript como solução

Por isso, queremos apresentar o TypeScript com mais detalhes, pois ele é a solução para esse tipo de problema.

O TypeScript é um superconjunto do JavaScript, conhecido como superset, que adiciona algo fundamental que o JavaScript não possui por padrão: a tipagem estática. A tipagem do JavaScript é dinâmica, o que pode ser considerada fraca. É como se estivéssemos colocando um cinto de segurança no nosso código.

Na documentação do TypeScript, há um exemplo interessante: um console.log em um objeto user na sua propriedade name. No entanto, esse objeto não possui a propriedade name. Sem o TypeScript, poderíamos cometer esse erro, e o código chegaria à produção. O TypeScript nos alerta que a propriedade name não existe no tipo que estamos mostrando, que é o objeto user, que possui firstName, lastName e role. Ele é inteligente o suficiente para prever o problema, sabendo que o código dará problema porque name não existe no objeto.

const user = {
  firstName: "Angela",
  lastName: "Davis",
  role: "Professor",
}

console.log(user.name)

// O TypeScript nos avisa:
// Property 'name' does not exist on type '{ firstName: string; lastName: string; role: string; }'.

Explicando os benefícios do TypeScript

O TypeScript não roda no navegador; é uma ferramenta que verifica nosso código e nos avisa sobre erros antes mesmo de o programa ser executado no navegador. Isso melhora a qualidade de vida de pessoas desenvolvedoras, oferecendo segurança de que, se o código compilar, ele tem uma chance maior de funcionar corretamente, e a maioria dos bugs provavelmente já foi resolvida. Podemos imaginar o TypeScript como um JavaScript com superpoderes. Todo código JavaScript válido é também um código TypeScript válido. Ele compila e, no final, nos entrega JavaScript puro, mas ajuda a pessoa desenvolvedora, oferecendo dicas e mostrando erros, como o exemplo mencionado na documentação.

O principal valor do TypeScript é a segurança e a produtividade, como o autocomplete que ele oferece na IDE e a documentação que gera automaticamente, se desejarmos. Por isso, é a linguagem ideal para grandes projetos, e frameworks como o Angular escolheram utilizar TypeScript por padrão.

O salto do JavaScript para o TypeScript - Conhecendo o projeto

Introduzindo o uso do TypeScript no Angular

Olá, pessoal. Agora que já conhecemos um pouco do TypeScript e entendemos melhor o que ele pode fazer, é hora de aprender como começar a utilizá-lo de fato. Usar o TypeScript não é tão simples quanto rodar apenas um Node em um arquivo JavaScript, mas também não é tão complicado. Ao escolhermos utilizar o Angular, ganhamos um presente, pois estamos dentro da carreira Angular. Vou explicar qual é esse presente.

O Angular é conhecido no mundo do front-end como um dos frameworks mais robustos que temos. Essa robustez e segurança se devem ao fato de que, desde o princípio, o Angular escolheu utilizar TypeScript por padrão. Isso significa que, assim que criamos nosso projeto Angular, já recebemos toda a configuração do TypeScript por padrão. Por isso, quando criamos o projeto do nosso curso, o TypeScript já foi instalado e estará disponível para nós.

Criando um novo projeto Angular

Para começar, vamos criar um novo projeto Angular utilizando o NPX. Isso nos permite não precisar instalar o Angular CLI globalmente. O comando que utilizamos é:

npx ng new 5532-typescript-books

Vou mostrar o nosso projeto funcionando. Ele é simples e o chamamos de "buscante". Será uma listagem de livros. No topo da página, temos um campo de busca onde podemos procurar por título, autor, data de publicação e editora. Em seguida, há uma lista estática. Algumas imagens vêm da internet, então podem ou não renderizar. Podemos substituir rapidamente por uma imagem padrão quando não há capa de livro disponível. Os livros estão estáticos no código, pois o objetivo do curso é aprender, interagir e dominar o TypeScript. Esta página web simples será suficiente para fazermos algumas buscas. Quando não houver resultados com o filtro aplicado, será exibida uma mensagem indicando que podemos buscar qualquer livro, junto com a imagem padrão.

Explorando a transpilação de TypeScript para JavaScript

Este projeto nos permitirá criar situações utilizando o TypeScript, mostrando onde ele faz diferença e nos ajuda a evitar erros, identificando os tipos que precisamos utilizar. O grande problema é que o navegador só entende JavaScript. Mesmo que o TypeScript traga benefícios, no final, o navegador do usuário só entenderá JavaScript. Por isso, precisamos encontrar uma forma de traduzir, transpilar ou compilar nosso código TypeScript em JavaScript, para que o navegador possa entender tudo o que criamos.

Como podemos fazer isso de forma organizada? A solução é o compilador do TypeScript, mas tudo isso foi abstraído para nós ao criarmos nosso projeto Angular. Para nos situarmos melhor, vou passar pelos passos que utilizei para criar este projeto, além de explicar um pouco da estrutura do nosso projeto Angular. Vamos focar nos arquivos de configuração do TypeScript, para que não precisemos configurá-los do zero. Sempre farei referência à documentação do TypeScript, que é nossa fonte de verdade e nos ajudará a entender como instalar e o que faz o TypeScript.

Analisando o arquivo de configuração tsconfig.json

Dentro da pasta src, já temos nosso aplicativo configurado, mas vamos focar principalmente em um arquivo: o tsconfig.json. Como o nome sugere, esse arquivo contém as configurações do TypeScript. Geralmente, não precisamos alterá-lo com frequência, especialmente em projetos Angular, pois ele já vem configurado. Alteramos sob demanda, ou seja, quando precisamos de uma configuração diferente, modificamos esse arquivo. A estrutura inicial dele contém várias opções, sendo um grande objeto com diversas configurações, como as opções de compilação. Aqui está um exemplo de como ele pode ser configurado:

{
  "compileOnSave": false,
  "compilerOptions": {
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true,
    "isolatedModules": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "ES2022",
    "module": "preserve"
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "typeCheckHostBindings": true,
    "strictTemplates": true
  },
  "files": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.spec.json"
    }
  ]
}

Se copiarmos a URL do "Veja Mais" e colarmos no navegador, encontraremos mais detalhes sobre a configuração na documentação do TypeScript. Caso não saibamos inglês, podemos usar ferramentas de tradução para entender melhor o que essas propriedades fazem. A flag strict habilita uma ampla gama de verificações de tipos, resultando em garantias mais robustas de correção do programa. Essa configuração exige que nosso programa siga mais as regras, não sendo tão flexível.

Detalhando as configurações do tsconfig.json

O arquivo tsconfig.json contém diversas outras configurações para pular ou não validações e cheques de bibliotecas, separar módulos, permitir ou não decoradores experimentais. Geralmente, modificamos essas configurações quando precisamos alterar algo ou quando, como equipe, decidimos ajustar certas configurações. Por exemplo, se não temos decoradores, podemos habilitar a experimentação deles.

Duas das principais configurações são o target, que define a versão do JavaScript para a qual o código final deve ser traduzido, como ECMAScript 2022, e o module, que define como o código deve ser modularizado, com opções como AMD, CommonJS, ESNext, entre outras. A documentação do TypeScript é extensa, e passar por todas as configurações levaria tempo. Por isso, fizemos um apanhado geral para entender que dentro do nosso projeto temos o tsconfig.json, tsconfig.spec.json e tsconfig.app.json. Esses arquivos estendem o tsconfig.json padrão, reaproveitando o que já está configurado, mas mudando algumas coisas. O tsconfig.spec.json é focado nos testes, configurando os tipos para Jasmine, que é o padrão nos projetos Angular, embora possamos usar Jest. Aqui está um exemplo de configuração para testes:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": [
      "jasmine"
    ]
  },
  "include": [
    "src/**/*.ts"
  ]
}

Configurando o build final com tsconfig.app.json

Já o tsconfig.app.json configura o build final da aplicação, definindo o que deve ser incluído ou excluído do bundle enviado ao usuário. No build final, não temos um arquivo .spec, pois os testes ficam apenas na máquina da pessoa desenvolvedora. Veja como ele é configurado:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "src/**/*.spec.ts"
  ]
}

Assim como o npm tem o package.json, o TypeScript é uma ferramenta de build, não sendo interpretado diretamente pelo navegador. Ele atua na máquina da pessoa desenvolvedora, ajudando a gerar um resultado esperado pelo navegador com mais segurança. O compilador TSC (TypeScript Compiler) é responsável por pegar o código TypeScript, verificar os tipos e, se tudo estiver correto, gerar o código JavaScript equivalente. Esse processo é chamado de transpilação. Quando rodamos um npm start, por exemplo, o Angular faz o build e, se não houver problemas, o aplicativo fica disponível na porta 4200.

Iniciando o servidor de desenvolvimento

Para iniciar o servidor de desenvolvimento, utilizamos o seguinte comando:

npm start

E o script correspondente no package.json é:

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build",
  "watch": "ng build --watch --configuration development",
  "test": "ng test"
}

O tsconfig.json é o coração do projeto TypeScript. Em um projeto apenas JavaScript, rodamos comandos como tsc --init e instalamos o TypeScript como um pacote npm (npm install typescript --save-dev). Todos os projetos terão o tsconfig.json, que garante que todos no time usem as mesmas configurações, assegurando que o projeto possua configurações padrão. Isso é fundamental para a consistência do nosso código.

Sobre o curso Typescript: aplicando tipagem e princípios SOLID

O curso Typescript: aplicando tipagem e princípios SOLID possui 243 minutos de vídeos, em um total de 46 atividades. Gostou? Conheça nossos outros cursos de JavaScript & TypeScript em Front-end, ou leia nossos artigos de Front-end.

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

Aprenda JavaScript & TypeScript acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas