Table of Contents
Curso de TypeScript Profissional 🚀
Bem-vindo ao curso definitivo para dominar o TypeScript no mundo real. Do zero absoluto até arquiteturas complexas, prepare-se para elevar sua carreira de desenvolvedor.
Diferencial
Foco em Engenharia: Não apenas sintaxe, mas como estruturar projetos escaláveis, usar padrões de projeto e garantir a qualidade com testes rigorosos.
🎯 O Que Você Vai Aprender
-
Segurança Extrema
Elimine erros de "undefined" e bugs em tempo de execução com tipagem estática rigorosa.
-
Fullstack Types
Aprenda a compartilhar tipos entre Node.js (Backend) e React (Frontend) com maestria.
-
:material-architecture: Arquitetura Limpa
Domine SOLID, DDD e Padrões de Projeto aplicados ao ecossistema TypeScript.
-
Projetos Reais
Saia da teoria com 16 mini-projetos práticos e um projeto final completo com Deploy.
📚 Estrutura do Curso (16 Aulas)
O curso é dividido em dois módulos estratégicos.
Módulo 1: Core & Linguagem (Aulas 01-08)
Construa sua base sólida na linguagem TypeScript. * Aula 01 - Introdução e Setup Profissional 🧠 * Aula 02 - Tipos Fundamentais e Inferência 🛠️ * Aula 03 - Tipos Avançados (Unions & Guards) 🧩 * Aula 04 - Interfaces e Modelagem 🏗️ * Aula 05 - Classes e Orientação a Objetos 🏛️ * Aula 06 - Generics (Programação Genérica) 📦 * Aula 07 - Utility Types (Produtividade) ⚙️ * Aula 08 - Manipulação Avançada de Tipos 🧪
Módulo 2: Aplicações & Ecossistema (Aulas 09-16)
Aplique o TypeScript no mercado de trabalho real. * Aula 09 - Módulos e Organização 📁 * Aula 10 - Backend com Node.js 🟢 * Aula 11 - Frontend com React ⚛️ * Aula 12 - APIs e Validação (Zod) 📡 * Aula 13 - Testes Automatizados (Jest) 🧪 * Aula 14 - Padrões de Projeto (Design Patterns) 🛡️ * Aula 15 - Clean Code e Arquitetura 📐 * Aula 16 - Projeto Final e Deploy 🚀
Success
Pronto para elevar seu nível? Clique no botão abaixo e inicie sua jornada profissional!
Aulas
Aulas do Curso 📚
Acesse aqui todo o conteúdo teórico dividido em dois grandes blocos: Core da Linguagem e Aplicações do Ecossistema.
-
Módulo 1: Core & Linguagem
A base sólida para escrever código seguro e previsível. Do setup até manipulação avançada.
- Aula 01 - Introdução e Setup Profissional
- Aula 02 - Tipos Fundamentais e Inferência
- Aula 03 - Tipos Avançados (Unions & Guards)
- Aula 04 - Interfaces e Modelagem
- Aula 05 - Classes e Orientação a Objetos
- Aula 06 - Generics (Programação Genérica)
- Aula 07 - Utility Types (Produtividade)
- Aula 08 - Manipulação Avançada de Tipos
-
Módulo 2: Ecossistema & Aplicações
Aplicação prática do TypeScript em ferramentas e frameworks de mercado.
Aula 01 - Introdução ao TypeScript e Setup Profissional 🧠
Objetivo
Nesta aula, você entenderá a evolução do JavaScript, por que o TypeScript se tornou o padrão da indústria e como configurar um ambiente de desenvolvimento profissional do zero.
1. Evolução do JavaScript e Problemas da Tipagem Dinâmica 🌊
O JavaScript nasceu em 1995 para ser uma linguagem de scripts simples para navegadores. Com o passar dos anos, ele assumiu o controle de aplicações complexas (Gmail, Facebook, VS Code). No entanto, sua natureza dinâmica e fracamente tipada traz desafios em larga escala.
O Problema da Tipagem Dinâmica 🧨
Em JS, você pode fazer isso:
Erros como undefined is not a function ou cannot read property of null são comuns e só aparecem em tempo de execução (quando o usuário está usando o app).
Atenção
Erros silenciosos em JavaScript são a maior causa de bugs em produção. O TypeScript resolve isso movendo a detecção de erros para o tempo de compilação.
2. O que é TypeScript? 🛡️
O TypeScript é um superset (superconjunto) do JavaScript criado pela Microsoft. Isso significa que todo código JavaScript é um código TypeScript válido, mas o TS adiciona uma camada de tipagem estática.
Por que usar TypeScript?
- Segurança: Detecta erros antes de rodar o código.
- Autocompletar (IntelliSense): O VS Code "entende" seu código e sugere propriedades.
- Refatoração: É muito mais seguro mudar nomes de funções ou variáveis em projetos grandes.
3. Setup Profissional 🛠️
Para começar, precisamos do Node.js instalado. O TypeScript é instalado via NPM (Node Package Manager).
Instalação Global
Conceito
O comando tsc é o TypeScript Compiler. Ele transforma seu código .ts em código .js que o navegador ou o Node conseguem entender.
4. O Coração do Projeto: tsconfig.json ⚙️
Todo projeto sério de TypeScript possui um arquivo de configuração chamado tsconfig.json. Ele define como o compilador deve se comportar.
Criando a Configuração
Dica
No tsconfig.json, ative sempre o "strict": true para garantir o máximo de segurança e as melhores práticas da linguagem.
5. Primeiro Projeto Estruturado (Laboratório) 🧪
Vamos criar nossa primeira estrutura profissional:
- Crie uma pasta
src/(onde ficará o código fonte). - Crie um arquivo
src/index.ts.
Visualizando o Fluxo de Trabalho (Mermaid)
graph LR;
TS[Código TypeScript .ts] -- "Compilador (tsc)" --> JS[Código JavaScript .js];
JS -- "Execução" --> Node[Node.js / Navegador];
style TS fill:#3178c6,color:#fff
style JS fill:#f7df1e,color:#000
Exemplo de Código no VS Code
interface Usuario {
nome: string;
id: number;
}
const novoUsuario: Usuario = {
nome: "Ricardo",
id: 1
};
console.log(`Olá, ${novoUsuario.nome}! Seu ID é ${novoUsuario.id}.`);
6. Exercícios de Fixação 📝
- Básico: Instale o TypeScript na sua máquina e verifique a versão.
- Básico: Crie um arquivo
ola.ts, declare uma variávelmsg: stringe imprima no console. - Intermediário: Gere o arquivo
tsconfig.jsone mude a opçãotargetparaES6. O que isso muda no JS gerado? - Intermediário: Tente atribuir um número a uma variável declarada como string. Observe o erro no VS Code.
- Desafio: Configure um script no
package.jsonchamadobuildque execute o comandotsc.
🚀 Mini-Projeto da Aula
Configure um ambiente onde o comando tsc -w (watch mode) fique monitorando sua pasta src/ e compilando automaticamente para uma pasta dist/.
Próxima Aula: Vamos mergulhar nos Tipos Fundamentais e Inferência e entender como o TS "adivinha" nossos tipos!
Aula 02 - Tipos Fundamentais e Inferência 🛠️
Objetivo
Nesta aula, exploraremos os pilares da tipagem no TypeScript: os tipos primitivos, as estruturas de dados básicas e o poderoso sistema de inferência que torna o código limpo e seguro ao mesmo tempo.
1. Tipos Primitivos 🧱
O TypeScript herda os tipos primitivos do JavaScript, mas permite que você os declare explicitamente.
| Tipo | Descrição | Exemplo |
|---|---|---|
string |
Textos | "Olá mundo" |
number |
Números (inteiros e decimais) | 42 ou 3.14 |
boolean |
Valores lógicos | true ou false |
Exemplo de Declaração
2. Arrays e Tuplas 📊
Arrays
Existem duas formas de declarar arrays:
Tuplas
As Tuplas permitem declarar um array com um número fixo de elementos e tipos conhecidos em posições específicas.
let pessoa: [string, number];
pessoa = ["Ricardo", 30]; // ✅ Correto
// pessoa = [30, "Ricardo"]; // ❌ Erro: Tipos na ordem errada
3. Enum, Any e Unknown 🎭
Enum
Permite definir um conjunto de constantes nomeadas, facilitando a legibilidade.
Any vs Unknown
Atenção
O tipo any desativa a checagem de tipos. Use apenas em casos extremos de migração de código.
any: Aceita qualquer coisa e permite qualquer operação.unknown: Aceita qualquer coisa, mas obriga você a verificar o tipo antes de usar (mais seguro).
4. Void e Never 🚫
void: Usado em funções que não retornam nenhum valor.never: Usado em funções que nunca terminam (como loops infinitos) ou que sempre lançam exceções.
function avisar(): void {
console.log("Aviso enviado!");
}
function erroFatal(msg: string): never {
throw new Error(msg);
}
5. Inferência de Tipos 🧠
O TypeScript é inteligente o suficiente para entender o tipo de uma variável sem que você precise escrever.
let curso = "TypeScript"; // O TS infere automaticamente que 'curso' é string
// curso = 10; // ❌ Erro: Não posso atribuir número a uma string
6. Strict Mode: O Coração da Qualidade 🛡️
Como vimos na Aula 1, o tsconfig.json possui o strict mode. Ele força o desenvolvedor a lidar com valores null e undefined, evitando os famosos erros de "quebra" em produção.
Visualizando a Hierarquia de Tipos (Mermaid)
graph TD;
Top[unknown / any] --> Prim[Primitivos];
Prim --> string;
Prim --> number;
Prim --> boolean;
Top --> Obj[Arrays / Objetos / Tuplas];
Obj --> Void[void];
Void --> Never[never];
7. Exercícios Práticos 📝
- Básico: Crie uma variável para cada tipo primitivo e atribua valores coerentes.
- Básico: Crie um array de strings e uma tupla contendo o nome e a versão de um software.
- Intermediário: Crie um
enumpara representar os dias da semana. - Intermediário: Crie uma função que receba um parâmetro
unknowne use otypeofpara imprimir se é uma string ou número. - Desafio: Tente criar uma função que retorne
nevere explique em qual cenário do mundo real ela seria útil.
🚀 Mini-Projeto da Aula
Crie um pequeno script de "Gerenciamento de Inventário" onde cada item é uma tupla [id: number, nome: string, preco: number, emEstoque: boolean]. Use um enum para as categorias dos itens.
Próxima Aula: Vamos aprender sobre Tipos Avançados como Union Types e Type Guards!
Aula 03 – Tipos Avançados 🧩
Objetivo
Nesta aula, aprenderemos a criar tipos flexíveis e poderosos usando uniões, interseções e aliases. Também veremos como o TypeScript nos ajuda a "estreitar" os tipos para garantir que o código seja 100% seguro contra erros de runtime.
1. Union Types (|) 🔗
O Union Type permite que uma variável tenha mais de um tipo possível. É como dizer: "esta variável pode ser uma string OU um número".
function imprimirId(id: number | string) {
console.log(`Seu ID é: ${id}`);
}
imprimirId(101); // ✅ OK
imprimirId("202"); // ✅ OK
// imprimirId(true); // ❌ Erro: boolean não é permitido
2. Type Alias 🏷️
Em vez de repetir tipos complexos em vários lugares, podemos criar um "apelido" usando a palavra-chave type.
3. Intersection Types (&) 🤝
Enquanto a união é um "ou", a interseção é um "e". Ela combina múltiplos tipos em um só. É muito usada para compor objetos.
type Pessoa = { nome: string };
type Empregado = { cargo: string };
type Desenvolvedor = Pessoa & Empregado;
const ricardo: Desenvolvedor = {
nome: "Ricardo",
cargo: "Tech Lead"
};
4. Literal Types 🎯
Podemos definir valores exatos que uma variável pode assumir. Isso é excelente para estados ou configurações.
type Alinhamento = "esquerda" | "centro" | "direita";
let texto: Alinhamento = "centro"; // ✅ OK
// texto = "cima"; // ❌ Erro: "cima" não está na lista
5. Narrowing e Type Guards 🛡️
Narrowing (Estreitamento) é o processo de o TypeScript "entender" qual é o tipo exato dentro de um fluxo lógico. Isso é feito usando Type Guards.
Exemplo com typeof
function processar(entrada: string | number) {
if (typeof entrada === "string") {
console.log(entrada.toUpperCase()); // Aqui o TS sabe que é string
} else {
console.log(entrada.toFixed(2)); // Aqui o TS sabe que é number
}
}
6. Estudo de Caso: Validação de Dados de API 📡
Ao receber dados de uma API, muitas vezes não sabemos o formato exato. Usar tipos avançados nos protege.
Visualizando a Validação (Mermaid)
graph TD;
API[Resposta da API] --> Guard{É um Usuário?};
Guard -- Sim --> Success[Acessar propriedades .nome e .id];
Guard -- Não --> Error[Tratar erro de formato];
style Guard fill:#f96,stroke:#333
7. Exercícios Práticos 📝
- Básico: Crie um Type Alias chamado
Statusque aceite os literais "ativo", "pendente" ou "inativo". - Básico: Crie uma função que receba um parâmetro que pode ser
numberounulle retorne o dobro se for número ou 0 se for null. - Intermediário: Crie dois tipos,
CarroeEletrico, e use uma interseção para criar umCarroEletrico. - Intermediário: Use o operador
incomo Type Guard para verificar se uma propriedade existe em um objeto. - Desafio: Crie uma função de validação de API que receba um objeto
anye use Type Guards para transformá-lo em um tipoProdutoseguro.
🚀 Mini-Projeto da Aula
Crie um sistema de "Notificações". O sistema deve aceitar notificações por Email ou SMS.
- Email tem endereco e assunto.
- SMS tem numero e mensagem.
Use Union Types e Narrowing para processar o envio corretamente.
Próxima Aula: Vamos explorar Interfaces e Modelagem de Domínio e entender a diferença entre interface e type!
Aula 04 – Interfaces e Modelagem de Domínio 🏗️
Objetivo
Nesta aula, aprenderemos a modelar objetos complexos usando Interfaces. Entenderemos a diferença entre interface e type e como construir contratos sólidos para aplicações corporativas.
1. O que são Interfaces? 📜
Uma Interface é um contrato que define a estrutura de um objeto. Ela diz quais propriedades e métodos um objeto deve ter, mas não como eles são implementados.
interface Livro {
titulo: string;
autor: string;
paginas?: number; // Propriedade opcional
readonly isbn: string; // Propriedade apenas de leitura
}
const meuLivro: Livro = {
titulo: "Clean Code",
autor: "Robert C. Martin",
isbn: "123-456-789"
};
2. Extensão de Interfaces (Herança de Contratos) 🧬
Podemos combinar interfaces para criar estruturas mais complexas e reutilizáveis.
interface Animal {
nome: string;
}
interface Mamifero extends Animal {
amamentar(): void;
}
const cachorro: Mamifero = {
nome: "Rex",
amamentar: () => console.log("Amamentando...")
};
3. Implementação em Classes 🏛️
As interfaces são fundamentais na Programação Orientada a Objetos (POO). Uma classe pode "assinar" um contrato de interface usando a palavra-chave implements.
interface Autenticavel {
login(): boolean;
}
class Usuario implements Autenticavel {
login(): boolean {
console.log("Usuário logado!");
return true;
}
}
4. Diferença entre Interface e Type Alias ⚖️
Ambos são muito parecidos, mas existem diferenças fundamentais:
| Característica | Interface | Type Alias |
|---|---|---|
| Extensibilidade | Pode ser estendida via extends. |
Pode ser combinada via interseção (&). |
| Declaration Merging | Se você definir duas com o mesmo nome, elas se fundem. | Não permite nomes duplicados. |
| Ideal para | Modelagem de objetos e POO. | Uniões, Primitivos, Funções e Tipos complexos. |
Dica Profissional
A recomendação oficial do TypeScript é: use Interface até que você precise de uma funcionalidade específica do Type.
5. Modelagem de Domínio (Entidades) 🗺️
Modelar o domínio é definir as "regras de negócio" através dos tipos. Em um e-commerce, teríamos:
Visualizando o Domínio (Mermaid)
classDiagram
class Produto {
+number id
+string nome
+number preco
}
class Cliente {
+string email
+string endereco
}
class Pedido {
+Produto[] itens
+Cliente cliente
+total() number
}
Pedido o-- Produto : contém
Pedido o-- Cliente : pertence a
6. Exercícios Práticos 📝
- Básico: Crie uma interface
Funcionariocom propriedadesnome,salarioe uma propriedade opcionalbonus. - Básico: Crie uma interface
Veiculoe useextendspara criar uma interfaceMoto. - Intermediário: Tente usar o "Declaration Merging" criando duas interfaces
Usuarioem partes diferentes do código e veja como o TS as une. - Intermediário: Crie uma interface para uma função que recebe dois números e retorna a soma deles.
- Desafio: Modele um sistema de biblioteca. Crie interfaces para
Autor,LivroeEmprestimo. Garanta que um empréstimo tenha uma data de início e uma data de devolução.
🚀 Mini-Projeto da Aula
Modele as entidades de um Sistema de Gestão Acadêmica.
- Interfaces para: Aluno, Professor, Disciplina e Turma.
- Uma turma deve conter um professor e uma lista de alunos.
- Utilize propriedades readonly para IDs que não podem ser alterados.
Próxima Aula: Vamos subir o nível com Classes e Programação Orientada a Objetos no TypeScript!
Aula 05 – Classes e Programação Orientada a Objetos 🏛️
Objetivo
Nesta aula, aplicaremos os conceitos de Programação Orientada a Objetos (POO) no TypeScript. Veremos como encapsular dados, usar modificadores de acesso e criar abstrações poderosas para sistemas escaláveis.
1. Modificadores de Acesso 🔒
Diferente do JavaScript puro, o TypeScript oferece modificadores que controlam quem pode acessar as propriedades e métodos de uma classe.
| Modificador | Descrição |
|---|---|
public |
(Padrão) Acesso total de qualquer lugar. |
private |
Acesso apenas dentro da própria classe. |
protected |
Acesso dentro da classe e de suas subclasses (herança). |
class ContaBancaria {
private saldo: number = 0; // Ninguém fora da classe mexe aqui
public depositar(valor: number): void {
this.saldo += valor;
}
}
2. Parâmetros Readonly e Shorthand Syntax ⚡
O TypeScript nos permite declarar e inicializar propriedades diretamente no construtor.
class Usuario {
constructor(
public readonly id: number,
private nome: string
) {}
}
const u = new Usuario(1, "Ricardo");
// u.id = 2; // ❌ Erro: Propriedade é readonly
3. Getters e Setters 🔄
Permitem aplicar lógica ao ler ou alterar um valor.
class Produto {
private _preco: number = 0;
get preco() { return this._preco; }
set preco(valor: number) {
if (valor < 0) throw new Error("Preço inválido!");
this._preco = valor;
}
}
4. Herança e Polimorfismo 🧬
A herança permite que uma classe herde comportamentos de outra, facilitando a reutilização de código.
class Funcionario {
constructor(public nome: string) {}
getBonus() { return 1000; }
}
class Gerente extends Funcionario {
getBonus() { return super.getBonus() + 5000; } // Polimorfismo
}
5. Classes Abstratas ☁️
Uma classe abstrata não pode ser instanciada diretamente. Ela serve como um "esqueleto" para outras classes.
Visualizando a Abstração (Mermaid)
classDiagram
class Pagamento {
<<abstract>>
+number valor
+processar()* void
}
class Cartao {
+processar() void
}
class Boleto {
+processar() void
}
Pagamento <|-- Cartao
Pagamento <|-- Boleto
6. Exercícios Práticos 📝
- Básico: Crie uma classe
Carrocom propriedadesmarca,modeloe um métodoacelerar. - Básico: Use o modificador
privateem uma propriedadevelocidadee crie um getter para ela. - Intermediário: Crie uma classe
Animalabstrata com um método abstratofazerSom()e implemente-o nas classesCachorroeGato. - Intermediário: Crie uma classe
Pessoae uma subclasseEstudante. Use osuper()no construtor da subclasse. - Desafio: Crie um sistema de "Contas". Uma
Contaabstrata e subclassesContaCorrenteeContaPoupanca. AContaCorrentedeve cobrar uma taxa em cada saque.
🚀 Mini-Projeto da Aula
Desenvolva um Sistema de RPG Simples.
- Crie uma classe base Personagem com nome, vida e ataque.
- Crie subclasses Guerreiro (mais vida) e Mago (mais ataque).
- Use encapsulamento para garantir que a vida nunca fique negativa.
Próxima Aula: Vamos aprender sobre Generics e como criar código que funciona com qualquer tipo!
Aula 06 – Generics (Programação Genérica) 📦
Objetivo
Nesta aula, desvendaremos o poder dos Generics. Você aprenderá a criar códigos altamente reutilizáveis e flexíveis que mantêm a segurança de tipos, independentemente do dado que estão processando.
1. O que são Generics? 🧬
Generics permitem que componentes (funções, classes ou interfaces) funcionem com uma variedade de tipos, ao invés de apenas um. Pense neles como "parâmetros para tipos".
O problema sem Generics
function retornarPrimeiro(lista: any[]): any {
return lista[0];
}
// ❌ Perdemos a informação do tipo original
A solução com Generics
function retornarPrimeiro<T>(lista: T[]): T {
return lista[0];
}
const n = retornarPrimeiro([1, 2, 3]); // n é inferido como number
const s = retornarPrimeiro(["a", "b"]); // s é inferido como string
2. Constraints (Restrições) ⛓️
Nem sempre queremos que o Generic aceite "qualquer" tipo. Podemos restringir o que ele aceita usando a palavra-chave extends.
interface TemComprimento {
length: number;
}
function logComprimento<T extends TemComprimento>(obj: T) {
console.log(obj.length);
}
logComprimento("Olá"); // ✅ OK (string tem length)
logComprimento([1, 2]); // ✅ OK (array tem length)
// logComprimento(10); // ❌ Erro: number não tem length
3. Classes Genéricas 🏗️
Classes também podem se beneficiar dessa flexibilidade. Um exemplo comum são as Pilhas ou Filas.
class Caixa<T> {
private conteudo?: T;
guardar(item: T) { this.conteudo = item; }
pegar() { return this.conteudo; }
}
const caixaDeNumeros = new Caixa<number>();
caixaDeNumeros.guardar(10);
4. Generics com Interfaces 📜
Podemos tornar nossas interfaces adaptáveis a diferentes tipos de resposta, muito comum em APIs.
interface RespostaAPI<T> {
data: T;
erro: string | null;
}
const respostaUsuario: RespostaAPI<{nome: string}> = {
data: { nome: "Ricardo" },
erro: null
};
5. Visualizando o Fluxo Genérico (Mermaid)
graph LR;
Entrada[Dados de Qualquer Tipo] --> Funcao{Função Genérica < T >};
Funcao --> Saída[Mantém o Tipo Original T];
style Funcao fill:#bbf,stroke:#333
6. Exercícios Práticos 📝
- Básico: Crie uma função genérica
identidade<T>que receba um argumento de tipoTe retorne exatamente esse argumento. - Básico: Crie um array genérico de strings.
- Intermediário: Crie uma função genérica que receba dois argumentos e retorne um array contendo ambos.
- Intermediário: Use constraints para garantir que um tipo genérico possua a propriedade
id: number. - Desafio: Crie uma interface
ListaPaginada<T>que contenha um array deitens: T[]e uma propriedadetotal: number.
🚀 Mini-Projeto da Aula
Crie um Repositório Genérico de Dados.
- O repositório deve ter métodos para: salvar(item: T), obterTodos(): T[] e buscarPorId(id: number): T | undefined.
- Teste o repositório criando uma instância para Produtos e outra para Usuarios.
Próxima Aula: Vamos explorar os Utility Types e descobrir como transformar tipos existentes de forma mágica!
Aula 07 – Utility Types e Manipulação de Tipos ⚙️
Objetivo
Nesta aula, conheceremos os utilitários integrados do TypeScript que facilitam a transformação de tipos existentes. Eles são essenciais para manter o código DRY (Don't Repeat Yourself) e flexível.
1. O que são Utility Types? 🛠️
Os Utility Types são tipos globais fornecidos pelo TypeScript que permitem realizar mapeamentos e transformações comuns de forma simples e segura.
2. Utilitários de Propriedades 📋
Partial
Torna todas as propriedades de um tipo opcionais. Útil para atualizações parciais de dados.
interface Usuario {
id: number;
nome: string;
email: string;
}
const atualizar: Partial<Usuario> = { nome: "Novo Nome" };
Required
O oposto do Partial. Torna todas as propriedades obrigatórias.
Readonly
Torna todas as propriedades apenas de leitura, impedindo alterações após a atribuição inicial.
3. Utilitários de Seleção ✂️
Pick
Cria um novo tipo escolhendo apenas algumas propriedades do tipo original.
Omit
Cria um novo tipo removendo as propriedades especificadas.
4. Utilitários de Estrutura 🏗️
Record
Cria um tipo de objeto onde as chaves são do tipo K e os valores são do tipo T.
type Configuracoes = Record<"tema" | "idioma", string>;
const config: Configuracoes = {
tema: "dark",
idioma: "pt-BR"
};
5. Mapped Types (Breve Introdução) 🗺️
Os Utility Types acima são construídos usando Mapped Types. Eles permitem que você percorra as propriedades de um tipo e crie um novo.
Visualizando a Transformação (Mermaid)
graph LR;
Original[Interface Original] -- "Partial< T >" --> Opcional[Todas Opcionais];
Original -- "Pick< T, K >" --> Selecionado[Apenas Algumas];
Original -- "Readonly< T >" --> Protegido[Apenas Leitura];
style Original fill:#e1f5fe,stroke:#01579b
6. Exercícios Práticos 📝
- Básico: Use
Partialpara criar uma função que aceite uma atualização parcial de um objetoProduto. - Básico: Crie uma interface
Configcom propriedades opcionais e useRequiredpara garantir que todas estejam presentes em uma variável. - Intermediário: Use
Pickpara extrair apenas otituloe adatade uma interfacePost. - Intermediário: Use
Recordpara criar um dicionário de traduções onde as chaves são "ola" e "tchau" e os valores são strings. - Desafio: Combine
OmiteReadonlypara criar um tipo de dado que não contenha o ID de umUsuarioe seja imutável.
🚀 Mini-Projeto da Aula
Crie um Transformador de Modelos.
- Defina uma interface robusta para um Pedido.
- Crie um tipo para a visualização resumida do pedido (Pick).
- Crie um tipo para a criação de um pedido (onde campos como id e dataGeracao são omitidos via Omit).
- Garanta que os dados da API sejam de apenas leitura (Readonly).
Próxima Aula: Vamos mergulhar na Manipulação Avançada de Tipos e entender tipos condicionais e o operador infer!
Aula 08 – Manipulação Avançada de Tipos 🧪
Objetivo
Nesta aula, exploraremos as funcionalidades mais avançadas do sistema de tipos do TypeScript. Aprenderemos a criar tipos que dependem de condições, extrair tipos de funções e gerar strings de tipos dinamicamente.
1. keyof e Indexed Access Types 🔑
Operador keyof
O operador keyof obtém todas as chaves de um tipo de objeto e as transforma em uma união de literais.
interface Carro {
marca: string;
ano: number;
}
type ChavesDoCarro = keyof Carro; // "marca" | "ano"
Indexed Access Types
Permite acessar o tipo de uma propriedade específica de outro tipo.
2. Tipos Condicionais 🛠️
Funcionam como um "if" para tipos. A sintaxe é similar ao operador ternário.
type EString<T> = T extends string ? "Sim" : "Não";
type Teste1 = EString<string>; // "Sim"
type Teste2 = EString<number>; // "Não"
3. O Operador infer 🔍
Usado dentro de tipos condicionais para "inferir" e extrair um tipo de dentro de outro (como o tipo de retorno de uma função).
type RetornoDeFuncao<T> = T extends (...args: any[]) => infer R ? R : any;
function soma(a: number, b: number): number { return a + b; }
type ResultadoSoma = RetornoDeFuncao<typeof soma>; // number
4. Template Literal Types 🖋️
Permitem criar novos tipos de string baseados em uniões de strings, usando a mesma sintaxe de template strings do JS.
type Cor = "vermelho" | "azul";
type Intensidade = "claro" | "escuro";
type CorCompleta = `${Cor}-${Intensidade}`;
// "vermelho-claro" | "vermelho-escuro" | "azul-claro" | "azul-escuro"
5. Visualizando a Lógica Condicional (Mermaid)
graph TD;
T[Tipo T] --> Cond{T extends U?};
Cond -- Verdadeiro --> X[Tipo X];
Cond -- Falso --> Y[Tipo Y];
style Cond fill:#f9f,stroke:#333
6. Exercícios Práticos 📝
- Básico: Use
keyofpara criar uma função que receba um objeto e uma de suas chaves e retorne o valor daquela chave. - Básico: Use
Indexed Access Typespara obter o tipo de um elemento dentro de um array de strings. - Intermediário: Crie um tipo condicional que verifique se um tipo é um array. Se for, retorne o tipo dos itens; se não, retorne o próprio tipo.
- Intermediário: Use
Template Literal Typespara gerar todas as combinações de chaves de um objeto CSS (ex:margin-top,margin-bottom, etc.). - Desafio: Use
inferpara criar um tipo que extraia o tipo do primeiro argumento de uma função.
🚀 Mini-Projeto da Aula
Crie um Gerador de Tipos Dinâmicos para APIs.
- Use Template Literal Types para criar rotas de API baseadas em recursos (ex: get-user, post-user).
- Use tipos condicionais para definir se a resposta de uma função deve ser um objeto ou um erro mapeado.
- Utilize keyof para validar se os filtros de busca enviados para a API pertencem ao modelo de dados.
Próxima Aula: Vamos organizar nossos projetos em Módulos e Organização Profissional de forma escalável!
Aula 09 – Módulos e Organização Profissional 📁
Objetivo
Nesta aula, aprenderemos a organizar código TypeScript de forma modular e escalável. Veremos como usar ES Modules, criar "Barrel Files" e configurar apelidos para caminhos, facilitando a manutenção de projetos grandes.
1. ES Modules (import/export) 📦
O TypeScript segue o padrão oficial do JavaScript para módulos (ESM). Isso permite que dividamos o código em vários arquivos e importemos apenas o que for necessário.
Exportando
Importando
2. Barrel Files (O arquivo index.ts) 🛢️
Um Barrel File é uma forma de consolidar múltiplos módulos em um único arquivo de saída, simplificando os imports no restante da aplicação.
Estrutura
Exemplo no index.ts
Agora você pode importar tudo de /models em vez de cada arquivo individualmente.
3. Namespaces (Legado vs Moderno) 🏛️
Antigamente, usava-se muito o namespace para organizar o código. Hoje, com o ES Modules, eles são menos comuns, mas ainda aparecem em bibliotecas legadas ou definições de tipos.
4. Path Aliases (Apelidos de Caminho) 🗺️
Em projetos grandes, os imports podem ficar confusos: ../../../../services/api. Podemos configurar o tsconfig.json para criar apelidos.
Configuração no tsconfig.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@services/*": ["services/*"],
"@models/*": ["models/*"]
}
}
}
5. Estruturação de Projeto Profissional 🏗️
Visualizando a Estrutura (Mermaid)
graph TD;
Root[Raiz do Projeto] --> Src[src];
Src --> Models[models - Interfaces e Types];
Src --> Services[services - Lógica e APIs];
Src --> Utils[utils - Funções utilitárias];
Src --> App[index.ts - Ponto de Entrada];
Root --> Dist[dist - Código JS Compilado];
Root --> Config[tsconfig.json];
6. Exercícios Práticos 📝
- Básico: Crie dois arquivos: um que exporte uma classe e outro que a importe e instancie.
- Básico: Use o
export defaultpara exportar uma função e importe-a com um nome diferente. - Intermediário: Crie uma pasta
utils, adicione três funções em arquivos separados e crie um "Barrel File" (index.ts) para exportá-las. - Intermediário: Tente configurar um
path aliasno seutsconfig.jsone use-o em um import. - Desafio: Refatore um projeto pequeno que use apenas um arquivo para a estrutura profissional sugerida no diagrama acima.
🚀 Mini-Projeto da Aula
Organize um Sistema de Cadastro de Clientes.
- Crie uma pasta domain para as interfaces.
- Crie uma pasta data para o repositório.
- Crie uma pasta shared para funções utilitárias (ex: formatadores de CPF).
- Use Barrel Files em cada pasta para exportar as funcionalidades de forma limpa.
Próxima Aula: Vamos colocar o TypeScript para rodar no lado do servidor com TypeScript com Node.js (Backend)!
Aula 10 – TypeScript com Node.js (Backend) 🟢
Objetivo
Nesta aula, aprenderemos a utilizar o TypeScript no desenvolvimento backend com Node.js. Veremos como configurar o ambiente, tipar requisições do Express, usar DTOs e garantir a segurança dos dados que entram na nossa API.
1. Configuração do Ambiente Backend 🛠️
Para rodar TypeScript no Node.js de forma eficiente, usamos ferramentas como ts-node-dev para desenvolvimento e tsc para produção.
Instalação das Dependências
O que são @types?
Como muitas bibliotecas JS não foram escritas em TS, a comunidade mantém o repositório DefinitelyTyped. O pacote @types/express fornece as definições de tipo para que o TS entenda o Express.
2. Tipagem de Requisições e Respostas 📨
O Express no TypeScript permite que tipemos os parâmetros, o corpo da requisição e a resposta.
import express, { Request, Response } from 'express';
const app = express();
app.use(express.json());
app.post('/usuarios', (req: Request, res: Response) => {
const { nome } = req.body; // req.body aqui é 'any' por padrão
return res.status(201).json({ mensagem: `Usuário ${nome} criado!` });
});
3. DTOs (Data Transfer Objects) e Validação 🛡️
Para evitar o uso de any e garantir que os dados recebidos são válidos, usamos o padrão DTO.
interface CriarUsuarioDTO {
nome: string;
email: string;
idade: number;
}
app.post('/usuarios', (req: Request, res: Response) => {
const dados: CriarUsuarioDTO = req.body;
// Agora temos autocompletar e segurança de tipos em 'dados'
});
4. Middleware Tipado 🧩
Middlewares são funções que rodam entre a requisição e a resposta. Eles também devem ser tipados.
import { NextFunction } from 'express';
function loggerMiddleware(req: Request, res: Response, next: NextFunction) {
console.log(`[${req.method}] ${req.url}`);
next();
}
5. Visualizando o Fluxo da API (Mermaid)
sequenceDiagram
participant Cliente
participant Express as Servidor Express (TS)
participant DTO as Validação DTO
participant DB as Banco de Dados
Cliente->>Express: POST /produtos (JSON)
Express->>DTO: Validar Tipos
DTO-->>Express: Dados OK
Express->>DB: Salvar Produto
DB-->>Express: Sucesso
Express-->>Cliente: 201 Created (JSON)
6. Exercícios Práticos 📝
- Básico: Configure um novo projeto Node.js com TypeScript e instale os tipos do Express.
- Básico: Crie uma rota
GETque retorne um objeto tipado com informações do servidor. - Intermediário: Crie uma interface
ProdutoDTOe use-a para tipar oreq.bodyde uma rota de criação. - Intermediário: Implemente um middleware que verifica se um
tokenestá presente no header da requisição. - Desafio: Crie uma mini API que gerencia uma lista em memória de "Tarefas" (Tasks). Use interfaces para as tarefas e garanta que as rotas de
POSTePUTusem DTOs.
🚀 Mini-Projeto da Aula
Desenvolva uma Mini API REST de Biblioteca.
- Rotas para listar, criar e buscar livros por ID.
- Use um array em memória para simular o banco de dados.
- Tipagem completa de Requests, Responses e Entidades.
- Implemente um tratamento de erros centralizado que use o tipo Error.
Próxima Aula: Vamos levar o TypeScript para o navegador com TypeScript com Frontend Moderno (React/Vue/Angular)!
Aula 11 – TypeScript com Frontend Moderno ⚛️
Objetivo
Nesta aula, aprenderemos como o TypeScript potencializa o desenvolvimento frontend, focando em React. Veremos como tipar componentes, props, hooks e o estado global da aplicação de forma profissional.
1. Por que TypeScript no Frontend? 🌐
Aplicações frontend lidam com muitas interações de usuário e dados dinâmicos. O TS ajuda a: - Garantir que as Props passadas para um componente estão corretas. - Evitar erros ao acessar o Estado (State). - Facilitar o uso de Context API e bibliotecas de gerenciamento de estado.
2. Componentes e Props Tipados 🧩
Em React com TS, definimos uma interface para as props do componente.
interface BotaoProps {
texto: string;
cor?: "primary" | "secondary";
onClick: () => void;
}
const Botao = ({ texto, cor = "primary", onClick }: BotaoProps) => {
return (
<button className={cor} onClick={onClick}>
{texto}
</button>
);
};
3. Hooks Tipados (useState / useRef) 🎣
O TS geralmente infere o tipo do useState, mas às vezes precisamos ser explícitos, especialmente com arrays ou objetos.
import { useState, useRef } from 'react';
// Inferência automática
const [contagem, setContagem] = useState(0);
// Explícito (Union Type)
const [usuario, setUsuario] = useState<Usuario | null>(null);
// Tipagem de Referências (DOM)
const inputRef = useRef<HTMLInputElement>(null);
4. Context API Tipada 🌍
Compartilhar estado global com segurança de tipos é um dos maiores benefícios do TS no React.
interface ThemeContextType {
tema: "light" | "dark";
toggleTema: () => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
5. Visualizando a Hierarquia de Componentes (Mermaid)
graph TD;
App[App.tsx] --> Header[Header.tsx];
App --> Main[MainContent.tsx];
Main --> Card["Card.tsx (Generic)"];
Main --> List["List.tsx (Generic)"];
style Card fill:#f9f,stroke:#333
style List fill:#f9f,stroke:#333
6. Exercícios Práticos 📝
- Básico: Crie um componente
Saudacaoque receba uma propnome: stringe exiba na tela. - Básico: Crie um estado usando
useStatepara armazenar uma lista de strings e exiba-os em uma lista<ul>. - Intermediário: Crie um componente de
Inputreutilizável que aceite todas as props padrão de um input HTML (useReact.InputHTMLAttributes). - Intermediário: Implemente um hook customizado
useLocalStorage<T>que seja genérico. - Desafio: Crie um componente
Tabela<T>genérico que receba uma lista de dados de tipoTe uma configuração de colunas para renderizá-los.
🚀 Mini-Projeto da Aula
Desenvolva um Dashboard de Tarefas (Todo List).
- Componentes para: Header, AddTodoForm, TodoList e TodoItem.
- Interfaces bem definidas para a entidade Todo (id, titulo, concluida).
- Use useState para gerenciar a lista e garanta que todas as funções de manipulação (adicionar, remover, alternar status) estejam devidamente tipadas.
Próxima Aula: Vamos aprender a conectar nossas aplicações ao mundo externo em Integração com APIs e Tipagem de Dados Externos!
Aula 12 – Integração com APIs e Tipagem de Dados Externos 📡
Objetivo
Nesta aula, aprenderemos a consumir serviços externos garantindo a integridade dos dados. Veremos como tipar respostas do Axios/Fetch, usar o padrão DTO para transformar dados e introduziremos a validação em runtime com bibliotecas como o Zod.
1. Fetch e Axios com TypeScript 🌐
Ao fazer uma requisição, o TypeScript não sabe o que virá da rede. Precisamos informar o tipo esperado para ter segurança ao manipular a resposta.
Exemplo com Axios
import axios from 'axios';
interface Usuario {
id: number;
name: string;
email: string;
}
async function buscarUsuario(id: number): Promise<Usuario> {
const { data } = await axios.get<Usuario>(`https://api.exemplo.com/users/${id}`);
return data;
}
2. O Padrão DTO (Data Transfer Object) 🔄
Muitas vezes, a API retorna dados em um formato bruto que não queremos usar diretamente no nosso frontend ou lógica de negócio. O DTO serve para mapear esses dados.
interface UsuarioAPI {
id: number;
full_name: string;
user_email: string;
}
interface UsuarioApp {
id: number;
nome: string;
email: string;
}
function mapToApp(user: UsuarioAPI): UsuarioApp {
return {
id: user.id,
nome: user.full_name,
email: user.user_email
};
}
3. Validação em Runtime com Zod 🛡️
O TypeScript remove os tipos no build final. Para garantir que os dados externos são realmente o que dizem ser enquanto o app roda, usamos o Zod.
Criando um Schema
import { z } from 'zod';
const UsuarioSchema = z.object({
id: z.number(),
nome: z.string().min(3),
email: z.string().email()
});
type Usuario = z.infer<typeof UsuarioSchema>;
// Validação
const resultado = UsuarioSchema.safeParse(dadosExternos);
if (!resultado.success) {
console.error("Dados inválidos!", resultado.error);
}
4. Tratamento de Erros de API ⚠️
Devemos tipar os erros para dar um feedback útil ao usuário.
try {
const user = await buscarUsuario(1);
} catch (error) {
if (axios.isAxiosError(error)) {
console.error("Erro na API:", error.response?.data.message);
} else {
console.error("Erro inesperado:", error);
}
}
5. Visualizando o Ciclo de Dados (Mermaid)
graph LR;
API[API Externa] -- "JSON" --> Schema{Validação Zod};
Schema -- "Falha" --> Erro[Tratamento de Erros];
Schema -- "Sucesso" --> DTO[Mapeador DTO];
DTO --> App[Estado da Aplicação];
style Schema fill:#f96,stroke:#333
style DTO fill:#bbf,stroke:#333
6. Exercícios Práticos 📝
- Básico: Crie uma interface para a resposta da API JSONPlaceholder (objetos de
Post). - Básico: Use o
fetchpara buscar dados e exiba o título do primeiro post no console (tipado). - Intermediário: Crie uma função que receba um objeto de API "sujo" e retorne um objeto "limpo" usando o padrão DTO.
- Intermediário: Instale o Zod e crie um schema para um objeto
Produto. Tente validar um objeto que falte propriedades obrigatórias. - Desafio: Implemente uma função genérica
request<T>(url: string)que use Axios e retorne umaPromise<T>, tratando erros de rede automaticamente.
🚀 Mini-Projeto da Aula
Desenvolva um Buscador de Repositórios do GitHub.
- Use a API pública do GitHub (https://api.github.com/users/USUARIO/repos).
- Crie interfaces para o Repositorio.
- Valide os dados recebidos com Zod.
- Exiba a lista de repositórios (nome, descrição e estrelas) em uma interface React ou no console do Node de forma tipada.
Próxima Aula: Vamos garantir que nosso código continue funcionando com Testes com TypeScript!
Aula 13 – Testes com TypeScript 🧪
Objetivo
Nesta aula, aprenderemos a garantir a qualidade e a estabilidade do nosso código usando testes automatizados. Veremos como configurar o Jest com TypeScript, criar mocks tipados e escrever testes unitários e de integração robustos.
1. Configurando o Jest com TypeScript 🛠️
O Jest é o framework de testes mais popular no ecossistema JS/TS. Para rodar testes em TS, usamos o ts-jest.
Instalação
2. Testes Unitários Tipados 🧩
Testes unitários testam a menor parte possível do código (funções, classes) de forma isolada.
// math.ts
export const somar = (a: number, b: number) => a + b;
// math.test.ts
import { somar } from './math';
describe('Função somar', () => {
it('deve retornar 5 ao somar 2 e 3', () => {
const resultado: number = somar(2, 3);
expect(resultado).toBe(5);
});
});
3. Mocks Tipados com TypeScript 🎭
Mocks são usados para substituir dependências complexas (como APIs ou Banco de Dados) por versões controladas durante os testes.
import axios from 'axios';
import { buscarUsuario } from './servico';
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
it('deve buscar um usuário com sucesso', async () => {
mockedAxios.get.mockResolvedValue({ data: { id: 1, nome: "Ricardo" } });
const user = await buscarUsuario(1);
expect(user.nome).toBe("Ricardo");
});
4. Testes de Integração 🔗
Testes de integração verificam se diferentes partes do sistema (como Rotas da API e Lógica de Negócio) funcionam bem juntas.
import request from 'supertest';
import app from './app';
describe('API de Usuários', () => {
it('deve criar um novo usuário', async () => {
const res = await request(app)
.post('/usuarios')
.send({ nome: 'Teste', email: 'teste@exemplo.com' });
expect(res.status).toBe(201);
expect(res.body.nome).toBe('Teste');
});
});
5. Visualizando o Ciclo de Testes (Mermaid)
graph TD;
Red["1. Falha (Vermelho)"] --> Green["2. Passa (Verde)"];
Green --> Refactor["3. Refatoração"];
Refactor --> Red;
style Red fill:#f99,stroke:#333
style Green fill:#9f9,stroke:#333
style Refactor fill:#99f,stroke:#333
6. Exercícios Práticos 📝
- Básico: Configure o Jest em um projeto TypeScript e crie um teste para uma função de multiplicão simples.
- Básico: Escreva um teste que verifique se uma função que lança erro realmente o faz (use
toThrow()). - Intermediário: Crie uma classe
Calculadorae escreva um conjunto de testes (describe) para todos os seus métodos. - Intermediário: Use o
jest.spyOn()para verificar se uma função foi chamada dentro de outra. - Desafio: Escreva um teste de integração para uma rota
GET /produtosque deve retornar uma lista de produtos tipados.
🚀 Mini-Projeto da Aula
Crie uma Suíte de Testes para o Repositório Genérico.
- Recupere o código do repositório da Aula 06.
- Escreva testes unitários para os métodos salvar, obterTodos e buscarPorId.
- Garanta 100% de cobertura nos métodos do repositório.
- Use mocks se o repositório depender de alguma função externa de persistência.
Próxima Aula: Vamos aprender a aplicar as melhores práticas de design com Padrões de Projeto com TypeScript!
Aula 14 – Padrões de Projeto com TypeScript 🛡️
Objetivo
Nesta aula, aprenderemos a elevar a qualidade do nosso software aplicando Padrões de Projeto (Design Patterns). Veremos como o TypeScript facilita a implementação de arquiteturas robustas usando Repositories, Services e Injeção de Dependência.
1. Padrão Repository e Service Layer 🏗️
A separação de responsabilidades é essencial. O Repository cuida do acesso aos dados, enquanto o Service cuida da lógica de negócio.
Estrutura
- Repository:
buscarTodos(),salvar(). - Service:
criarNovoUsuario(),validarRegrasDeNegocio().
interface IUsuarioRepository {
salvar(usuario: Usuario): Promise<void>;
}
class UsuarioService {
constructor(private repo: IUsuarioRepository) {}
async registrar(nome: string) {
// Lógica de negócio aqui
await this.repo.salvar({ nome });
}
}
2. Injeção de Dependência (DI) 💉
Em vez de criar as dependências dentro da classe, nós as "injetamos" (geralmente pelo construtor). Isso torna o código mais fácil de testar (usando mocks).
// No mundo real, usamos frameworks como Inversify ou Nestjs
const meuRepo = new SqlUsuarioRepository();
const meuServico = new UsuarioService(meuRepo);
3. Padrão Factory 🏭
Usado quando a criação de um objeto é complexa ou depende de condições.
class PagamentoFactory {
static criar(tipo: "cartao" | "boleto") {
if (tipo === "cartao") return new PagamentoCartao();
return new PagamentoBoleto();
}
}
4. Padrão Strategy ♟️
Permite definir uma família de algoritmos, colocá-los em classes separadas e tornar seus objetos intercambiáveis.
interface EstrategiaDesconto {
calcular(valor: number): number;
}
class DescontoBlackFriday implements EstrategiaDesconto {
calcular(valor: number) { return valor * 0.5; }
}
5. Visualizando o Padrão Repository (Mermaid)
graph LR;
Controller[Controller / API] --> Service[Service - Lógica];
Service --> RepoInterface[Interface do Repositório];
RepoInterface --> SqlRepo[SQL Repository];
RepoInterface --> MongoRepo[Mongo Repository];
style RepoInterface fill:#f9f,stroke:#333
6. Exercícios Práticos 📝
- Básico: Crie uma classe
LogServicee use injeção de dependência para passá-la para outra classe. - Básico: Implemente um
Factoryque crie diferentes tipos deNotificacao(Email, SMS). - Intermediário: Implemente o padrão
Strategypara diferentes formas de calcular o frete (Normal, Expresso). - Intermediário: Crie uma interface
IUserRepositorye implemente uma versãoInMemoryUserRepository. - Desafio: Refatore o Mini-Projeto da Aula 10 aplicando os padrões Repository e Service Layer.
🚀 Mini-Projeto da Aula
Implemente um Sistema de Processamento de Pagamentos. - Use o padrão Factory para criar o método de pagamento. - Use o padrão Strategy para aplicar diferentes taxas dependendo do método. - Use Injeção de Dependência para passar o serviço de log para o processador de pagamentos. - Tudo deve ser 100% tipado com interfaces.
Próxima Aula: Vamos aprender a escrever código limpo e entender a arquitetura em Clean Code e Arquitetura!
Aula 15 – Clean Code e Arquitetura 📐
Objetivo
Nesta aula, consolidaremos os conhecimentos técnicos com os princípios de código limpo e arquitetura. Aprenderemos a aplicar o SOLID, organizar o projeto em camadas e entenderemos os fundamentos do Domain-Driven Design (DDD).
1. Princípios SOLID com TypeScript 💎
O SOLID é um conjunto de cinco princípios que tornam o software mais compreensível, flexível e sustentável.
| Letra | Princípio | Descrição no TS |
|---|---|---|
| S | Single Responsibility | Uma classe/função deve ter apenas uma razão para mudar. |
| O | Open/Closed | Aberto para extensão, fechado para modificação. |
| L | Liskov Substitution | Subclasses devem ser substituíveis por suas classes base. |
| I | Interface Segregation | Muitas interfaces específicas são melhores que uma geral. |
| D | Dependency Inversion | Dependa de abstrações (interfaces), não de implementações. |
2. Separação de Responsabilidades e Camadas 🏢
Uma aplicação profissional é dividida em camadas para facilitar a manutenção e os testes.
- Domain: Onde vivem as regras de negócio e interfaces principais.
- Application: Casos de uso e lógica de orquestração (Services).
- Infrastructure: Detalhes técnicos (Base de dados, chamadas de API, Frameworks).
3. Domain-Driven Design (Introdução) 🗺️
O DDD foca em entender o problema do cliente e modelar o software fielmente a esse problema. - Entities: Objetos com identidade única (ex: Usuário com ID). - Value Objects: Objetos definidos por seus atributos (ex: Endereço). - Repositories: Porta de saída para persistência.
4. Boas Práticas Profissionais 🚀
- Nomes Significativos: Use nomes que revelem a intenção (
isValidem vez dev). - Funções Pequenas: Cada função deve fazer apenas uma coisa.
- Evite Comentários Óbvios: O código deve ser autoexplicativo através de tipos e bons nomes.
5. Visualizando a Arquitetura em Camadas (Mermaid)
graph TD;
External[Mundo Externo / UI / API] --> Infra[Infraestrutura];
Infra --> App[Aplicação / Services];
App --> Domain[Domínio / Entidades];
style Domain fill:#f9f,stroke:#333
6. Exercícios Práticos 📝
- Básico: Identifique uma violação do princípio de Responsabilidade Única em um código e proponha uma refatoração.
- Básico: Renomeie variáveis e funções de um código legado para nomes mais semânticos e tipados.
- Intermediário: Crie uma interface "Geral" e quebre-a em três interfaces menores (Segregação de Interface).
- Intermediário: Implemente um "Value Object" para representar um CPF, incluindo a validação no construtor.
- Desafio: Esboce a estrutura de pastas de um projeto seguindo a separação entre Domain, Application e Infrastructure.
🚀 Mini-Projeto da Aula
Refatore o seu projeto acumulado até aqui (Sistema de Pagamentos ou Biblioteca) aplicando os princípios de Clean Code e SOLID. - Garanta que nenhuma função tenha mais de 20 linhas. - Verifique se a camada de domínio é independente de bibliotecas externas (como o Express). - Utilize Injeção de Dependência para todos os serviços e repositórios.
Próxima Aula: É hora do Projeto Final e Deploy! Vamos colocar tudo em prática e lançar nossa aplicação!
Aula 16 – Projeto Final e Deploy 🚀
Objetivo
Chegamos ao fim da nossa jornada! Nesta aula, consolidaremos tudo o que aprendemos em um projeto completo. Veremos como preparar nosso código para produção, Dockerizar a aplicação e realizar o deploy em nuvem.
1. O Projeto Final: Sistema de E-commerce Full-Stack 🛒
O desafio final é construir uma API robusta e uma interface simples que se conectem.
Requisitos Técnicos
- Tipagem: 100% dos dados tipados (Interfaces, Types, Enums).
- Backend: Node.js + Express com Repository Pattern e Services.
- Frontend: React com Hooks e Context API tipados.
- Segurança: Validação de dados externos com Zod.
- Qualidade: Pelo menos 20% de cobertura de testes unitários com Jest.
2. Preparando o Build para Produção 🏗️
O código TypeScript não roda diretamente em servidores de produção. Precisamos transpilá-lo para JavaScript.
Atenção
Sempre verifique se a pasta dist/ está no seu .gitignore. Você deve subir o código fonte (src/), não o código compilado.
3. Dockerização (Opcional Profissional) 🐳
O Docker garante que sua aplicação rode da mesma forma em qualquer máquina.
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]
4. Estratégias de Deploy 🚀
Opções Populares:
- Vercel / Netlify: Excelentes para o Frontend (React).
- Railway / Render / Heroku: Ótimos para o Backend (Node.js).
- AWS / Google Cloud: Para projetos de grande escala.
5. Visualizando o Ciclo de Vida do Projeto (Mermaid)
graph TD;
Dev[Desenvolvimento TS] --> Test[Testes Automatizados];
Test --> Build[Build / Transpilação];
Build --> Artifact[Artefato JS];
Artifact --> Deploy[Deploy em Nuvem];
Deploy --> Monitor[Monitoramento e Feedbacks];
style Deploy fill:#f96,stroke:#333
6. Exercícios Práticos 📝
- Básico: Execute o comando
tsce veja o JavaScript gerado na pasta de saída. - Básico: Crie um arquivo
.gitignoreque ignore as pastasnode_modulesedist. - Intermediário: Configure um script no
package.jsonchamadostartque rode o código já compilado. - Intermediário: Crie um
Dockerfilebásico para sua aplicação Node.js. - Desafio: Realize o deploy de uma pequena API TypeScript em um serviço gratuito como o Render ou Railway.
🎓 Conclusão do Curso
Parabéns! Você completou o treinamento TypeScript Profissional. Você agora domina uma das linguagens mais requisitadas do mercado e está pronto para construir aplicações escaláveis, seguras e de alta qualidade.
Obrigado por participar! Continue praticando e explorando a documentação oficial em typescriptlang.org.
Exercícios
Listas de Exercícios 🏋️
Pratique o que aprendeu com listas graduadas (Fácil, Médio, Desafio) focadas em TypeScript Profissional.
-
Módulo 1: Core & Linguagem
-
Módulo 2: Ecossistema & Apps
Exercícios: Aula 01 – Introdução ao TypeScript e Setup Profissional 🧠
🟢 Nível: Básico
- Instalação Local: Inicialize um projeto Node.js (
npm init -y) e instale o TypeScript como dependência de desenvolvimento. - Configuração Inicial: Gere o arquivo
tsconfig.jsone altere a propriedadeoutDirpara "./dist" erootDirpara "./src".
🟡 Nível: Intermediário
- Compilação Manual: Crie um arquivo
src/app.ts, adicione umconsole.loge execute o comandonpx tscpara gerar o arquivo na pastadist. - Watch Mode: Configure o compilador para monitorar alterações automaticamente (
watch mode) e valide se o arquivo JS é atualizado ao salvar o TS.
🔴 Nível: Desafio
- Automação com NPM: No seu
package.json, crie dois scripts:build(para compilar uma única vez) edev(para rodar o compilador em modo watch). Teste ambos os comandos via terminal.
Exercícios: Aula 02 – Tipos Fundamentais e Inferência 🛠️
🟢 Nível: Básico
- Declaração de Primitivos: Crie variáveis para armazenar seu nome, sua idade e se você gosta de TypeScript (booleano), usando tipagem explícita.
- Arrays Simples: Crie um array de números contendo os anos em que você realizou cursos e um array de strings com os nomes desses cursos.
🟡 Nível: Intermediário
- Trabalhando com Tuplas: Crie uma tupla chamada
coordenadasque aceite dois números (latitude e longitude). - Uso de Enums: Crie um
enumchamadoNivelAcessocom as opçõesADMIN,USEReGUEST. Crie uma variável do tipo deste enum.
🔴 Nível: Desafio
- Segurança com Unknown: Crie uma função que aceita um parâmetro do tipo
unknown. Dentro dela, usetypeofpara verificar se é uma string; se for, imprima-a em letras maiúsculas; caso contrário, imprima uma mensagem genérica.
Exercícios: Aula 03 – Tipos Avançados 🧩
🟢 Nível: Básico
- Union Types: Crie uma variável que possa receber
stringouboolean. - Literal Types: Crie um tipo chamado
Alinhamentoque permita apenas os valores"left","center"ou"right".
🟡 Nível: Intermediário
- Intersection Types: Crie dois tipos de objetos,
Pessoa(com nome) eTrabalhador(com cargo), e crie um terceiro tipo que seja a interseção de ambos. - Narrowing com typeof: Escreva uma função que receba
number | stringe retorne o dobro se for número ou o comprimento se for string.
🔴 Nível: Desafio
- Validação Completa: Crie um Type Alias para um
UsuarioAPIque pode ter um ID numérico ou sernull. Use Type Guards para garantir que você só acesse propriedades do ID se ele não for nulo.
Exercícios: Aula 04 – Interfaces e Modelagem de Domínio 🏗️
🟢 Nível: Básico
- Interface Simples: Crie uma interface
Usuariocomnome,idadee uma propriedade opcionalsite. - Extensão: Crie uma interface
Adminque estendaUsuarioe adicione a propriedadenivel(número).
🟡 Nível: Intermediário
- Readonly: Crie uma interface
Configuracaoonde todas as propriedades sejamreadonly. Tente alterar uma após a criação. - Interface de Função: Defina uma interface para uma função que receba dois números e retorne um booleano.
🔴 Nível: Desafio
- Modelagem de Sistema: Modele as interfaces para um sistema de "Pedidos de Ecommerce". Deve haver um
Cliente, umProdutoe umPedido(que contém uma lista de produtos e o cliente).
Exercícios: Aula 05 – Classes e Programação Orientada a Objetos 🏛️
🟢 Nível: Básico
- Classe Simples: Crie uma classe
Animalcom um métodofalar(). - Herança: Crie uma classe
Cachorroque herda deAnimale sobrescreva o métodofalar()para latir.
🟡 Nível: Intermediário
- Modificadores de Acesso: Crie uma classe
Contacom um atributosaldoprivado. Adicione métodos para depositar e ver o saldo. - Getters e Setters: Crie uma classe
Retangulocomlarguraealtura. Use getters e setters para garantir que os valores sejam sempre positivos.
🔴 Nível: Desafio
- Abstração: Crie uma classe abstrata
Funcionariocom um método abstratocalcularSalario(). Implemente as subclassesDesenvolvedoreGerentecom lógicas de cálculo diferentes.
Exercícios: Aula 06 – Generics (Programação Genérica) 📦
🟢 Nível: Básico
- Função Generics: Escreva uma função genérica chamada
duplicar<T>que receba um item e retorne um array contendo o item duas vezes. - Array Genérico: Crie uma função que receba um array genérico e retorne o último elemento.
🟡 Nível: Intermediário
- Classe Genérica: Crie uma classe
Pilha<T>que permita adicionar (push) e remover (pop) itens de um tipo genérico. - Constraints: Crie uma função genérica que aceite apenas objetos que possuam a propriedade
.id.
🔴 Nível: Desafio
- Interface Genérica: Crie uma interface para uma
RespostaAPI<T>que contenha os camposstatus,data(do tipo T) eerror. Teste-a com diferentes tipos de dados.
Exercícios: Aula 07 – Utility Types e Manipulação de Tipos ⚙️
🟢 Nível: Básico
- Partial: Use o utilitário
Partialem uma interfaceUsuariopara criar uma variável que tenha apenas o nome. - Readonly: Crie uma versão
Readonlyde um objetoCarroe tente alterar uma propriedade.
🟡 Nível: Intermediário
- Pick e Omit: A partir de uma interface
Funcionario, usePickpara criar um tipo com apenasnomeecargo, eOmitpara criar um tipo que não tenha osalario. - Record: Use o
Recordpara mapear códigos de erro (números) para mensagens de erro (strings).
🔴 Nível: Desafio
- Mapeamento de API: Crie um tipo que represente a resposta de uma "atualização de perfil", onde todos os campos do usuário original são opcionais, exceto o
id, que deve ser obrigatório.
Exercícios: Aula 08 – Manipulação Avançada de Tipos 🧪
🟢 Nível: Básico
- keyof: Use o operador
keyofem uma interfaceCarropara criar uma união de suas chaves. - Indexed Access: Dada a interface
Config, obtenha o tipo da propriedadeversaousando acesso indexado.
🟡 Nível: Intermediário
- Conditional Types: Crie um tipo que verifique se um dado tipo
Té uma string. Se for, retorne"TEXTO", se não, retorne"OUTRO". - Template Literals: Crie um tipo que combine as direções
"Norte" | "Sul"com as intensidades"Forte" | "Fraca".
🔴 Nível: Desafio
- Uso de infer: Escreva um tipo utilitário que extraia o tipo do primeiro elemento de uma tupla genérica usando
infer.
Exercícios: Aula 09 – Módulos e Organização Profissional 📁
🟢 Nível: Básico
- Export/Import: Crie um módulo para uma classe
Calculadorae importe-o em outro arquivo para realizar uma soma. - Export Default: Exporte uma constante por padrão e importe-a com um apelido à sua escolha.
🟡 Nível: Intermediário
- Barrel Files: Crie uma estrutura de pastas para
controllerse crie um arquivoindex.tsque exporta tudo o que há dentro dela. - Namespaces: Crie um
namespacepara agrupar funções de validação de formulário (e-mail, senha).
🔴 Nível: Desafio
- Path Aliases: Configure um alias
@modelsnotsconfig.jsone use-o para importar uma interface de uma pasta profunda do projeto.
Exercícios: Aula 10 – TypeScript com Node.js (Backend) 🟢
🟢 Nível: Básico
- Instalação Backend: Inicialize um projeto Node, instale o
expresse os tipos@types/express. - Primeira Rota: Crie uma rota
GET /que retorne uma mensagem de boas-vindas tipada.
🟡 Nível: Intermediário
- Tipagem de Body: Crie uma rota
POST /usuariose use uma interface para tipar os dados recebidos noreq.body. - Middleware de Log: Implemente um middleware que registre o método e a URL de cada requisição.
🔴 Nível: Desafio
- Tratamento de Erros: Crie um middleware de erro customizado que capture exceções e retorne uma resposta JSON padronizada e tipada.
Exercícios: Aula 11 – TypeScript com Frontend Moderno ⚛️
🟢 Nível: Básico
- Props de Componente: Crie um componente
Botaoem React que receba as propslabel(string) eativo(boolean). - Estado Simples: Use o
useStatepara criar um contador tipado que só aceite números.
🟡 Nível: Intermediário
- Eventos: Tipar o evento de um formulário (
React.FormEvent) em uma funçãohandleSubmit. - useRef Tipado: Crie um formulário onde um botão "Focar" use um
useRefpara dar foco a um input de texto.
🔴 Nível: Desafio
- Context API: Crie um contexto para gerenciar as informações do usuário logado. Defina uma interface para o contexto e garanta que o provedor seja tipado corretamente.
Exercícios: Aula 12 – Integração com APIs e Tipagem de Dados Externos 📡
🟢 Nível: Básico
- Interface de API: Crie uma interface para o objeto retornado por uma API de clima (ex: OpenWeather).
- Fetch Tipado: Realize um
fetchpara uma URL de teste e use o operadoraspara converter o resultado para a sua interface.
🟡 Nível: Intermediário
- Axios Generics: Use o Axios para fazer um
getgenérico chamando uma interfacePost. - Mapeamento DTO: Crie uma função que transforme um objeto de usuário da API (com nomes em snake_case) para um objeto da aplicação (com nomes em camelCase).
🔴 Nível: Desafio
- Zod Schema: Crie um schema Zod para validar a entrada de um formulário de login (email e senha com requisitos de tamanho).
Exercícios: Aula 13 – Testes com TypeScript 🧪
🟢 Nível: Básico
- Setup Jest: Configure um arquivo
jest.config.jsbásico para aceitar arquivos TypeScript. - Primeiro Teste: Crie uma função que retorne a soma de três números e escreva um teste que valide o resultado.
🟡 Nível: Intermediário
- Teste de Exceção: Escreva uma função que valide a idade de um usuário e lance um erro se for menor de 18. Teste se o erro é lançado corretamente.
- Mock de Função: Use
jest.fn()para simular o comportamento de um callback passado para uma função de processamento.
🔴 Nível: Desafio
- Mock de API: Use o
jest.mock('axios')para simular uma chamada de API e validar se o seu serviço está tratando a resposta corretamente.
Exercícios: Aula 14 – Padrões de Projeto com TypeScript 🛡️
🟢 Nível: Básico
- Injeção de Dependência: Crie uma função que receba um objeto de configuração por parâmetro (em vez de usá-lo globalmente).
- Singleton: Implemente o padrão Singleton para uma classe de Gerenciamento de Configurações.
🟡 Nível: Intermediário
- Repository Pattern: Crie uma interface
IRepository<T>e implemente uma versão básica para uma entidadeProduto. - Factory Pattern: Implemente uma fábrica de objetos que crie diferentes tipos de "Veículos".
🔴 Nível: Desafio
- Strategy Pattern: Use o padrão Strategy para implementar diferentes formas de cálculo de imposto baseadas no tipo de produto.
Exercícios: Aula 15 – Clean Code e Arquitetura 📐
🟢 Nível: Básico
- Nomes Semânticos: Refatore uma função com nomes genéricos (ex:
a,b,fn1) para nomes que expliquem sua função. - Função de Responsabilidade Única: Quebre uma função que faz duas coisas (ex: valida e salva no banco) em duas funções separadas.
🟡 Nível: Intermediário
- Inversão de Dependência: Refatore uma classe que instancia diretamente um serviço para que ela receba o serviço no construtor.
- Segregação de Interface: Quebre uma interface "gorda" que tem 10 métodos em três interfaces menores e mais específicas.
🔴 Nível: Desafio
- Domain Entities: Crie uma Entidade de Domínio para um "Pedido" que contenha uma lógica interna para calcular o total sem depender de serviços externos.
Exercícios: Aula 16 – Projeto Final e Deploy 🚀
🟢 Nível: Básico
- Build de Produção: Execute o comando
npm run builde analise o código gerado na pastadist. - Scripts NPM: Configure um script
startque execute o arquivodist/index.js.
🟡 Nível: Intermediário
- Docker Básico: Escreva um
Dockerfileque copie apenas o necessário para rodar a aplicação já compilada. - Variáveis de Ambiente: Configure o seu projeto para ler a porta do servidor de uma variável de ambiente (
process.env.PORT).
🔴 Nível: Desafio
- Pipeline CI/CD: Documente os passos necessários para configurar o deploy automático do seu projeto no GitHub Pages ou Vercel.
Projetos
Projetos Práticos 🚀
Construa portfólio com 16 mini-projetos reais e marcos importantes na sua trajetória.
-
Módulo 1: Core & Linguagem
-
Módulo 2: Ecossistema & Apps
Mini-Projeto: Aula 01 – Setup do Workspace Profissional 🛠️
Objetivo
Configurar um ambiente de desenvolvimento TypeScript completo, pronto para produção, seguindo as melhores práticas de organização de pastas e automação de scripts.
🏗️ Requisitos do Projeto
- Inicializar um projeto Node.js.
- Configurar o TypeScript com
tsconfig.json. - Organizar a estrutura de pastas (
srcedist). - Automatizar o processo de build e execução.
🛠️ Passo a Passo
1. Inicialização
Abra o terminal na pasta do projeto e execute:
2. Configuração do TS
Gere o arquivo de configuração e ajuste as seguintes propriedades:
Configurações recomendadas no tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"rootDir": "./src",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
3. Scripts de Automação
No arquivo package.json, adicione:
"scripts": {
"dev": "ts-node-dev --respawn --transpile-only src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
}
4. Código de Teste
Crie a pasta src/ e o arquivo index.ts:
✅ Verificação Final
- Execute
npm run deve verifique se o log aparece no terminal. - Altere o texto da mensagem e veja se o servidor reinicia sozinho.
- Execute
npm run builde verifique se a pastadist/foi criada com o arquivo.js.
Mini-Projeto: Aula 02 – Calculadora de IMC (Tipos Primitivos) ⚖️
Objetivo
Praticar o uso de tipos primitivos (number, string), inferência de tipos e interação simples via console.
🏗️ Requisitos do Projeto
- Receber peso e altura do usuário.
- Calcular o IMC (Peso / Altura²).
- Exibir o resultado formatado com uma classificação.
- Usar tipagem explícita para as variáveis principais.
🛠️ Passo a Passo
1. Estrutura do Código
No seu arquivo src/index.ts, defina as variáveis:
const nome: string = "Ricardo";
const peso: number = 85;
const altura: number = 1.80;
function calcularIMC(p: number, a: number): number {
return p / (a * a);
}
2. Lógica de Classificação
Use o resultado para determinar a categoria:
const imc = calcularIMC(peso, altura);
let classificacao: string;
if (imc < 18.5) classificacao = "Abaixo do peso";
else if (imc < 25) classificacao = "Peso normal";
else classificacao = "Sobrepeso";
console.log(`${nome}, seu IMC é ${imc.toFixed(2)} (${classificacao})`);
✅ Desafio Extra
- Use um
enumpara as categorias de classificação (ABAIXO, NORMAL, SOBREPESO). - Crie uma tupla para armazenar os dados do usuário:
[string, number, number].
Mini-Projeto: Aula 03 – Gerenciador de Inventário (Tipos Avançados) 📦
Objetivo
Utilizar Union Types, Type Aliases e Intersection Types para modelar um sistema de inventário de produtos.
🏗️ Requisitos do Projeto
- Definir tipos para diferentes categorias de produtos (Eletrônicos, Alimentos).
- Usar intersecção para criar modelos completos.
- Implementar uma função que aceita diferentes tipos de IDs (número ou string).
🛠️ Passo a Passo
1. Modelagem com Type Aliases
type Categoria = "Eletronico" | "Alimento" | "Vestuario";
type ProdutoBase = {
id: string | number;
nome: string;
preco: number;
categoria: Categoria;
};
type Especificacoes = {
peso: number;
dimensoes?: string;
};
// Intersection Type
type ProdutoCompleto = ProdutoBase & Especificacoes;
2. Manipulação Tipada
Crie um array de produtos e uma função para buscar por ID.
const inventario: ProdutoCompleto[] = [
{ id: 1, nome: "Celular", preco: 2000, categoria: "Eletronico", peso: 0.2 },
{ id: "A-123", nome: "Maçã", preco: 5, categoria: "Alimento", peso: 0.1 }
];
function buscar(id: string | number) {
return inventario.find(p => p.id === id);
}
✅ Desafio Extra
- Implemente um
Type Guardpara verificar se um produto é da categoria "Eletronico". - Use
Literal Typespara definir o status do produto:"em_estoque" | "esgotado".
Mini-Projeto: Aula 04 – Sistema de Gerenciamento de Tarefas (Interfaces) ✅
Objetivo
Modelar um sistema de tarefas (To-Do) corporativo usando interfaces, propriedades opcionais e herança de interfaces.
🏗️ Requisitos do Projeto
- Interface para
Usuario. - Interface para
Tarefacom campos opcionais. - Interface para
Projetoque agrupa várias tarefas. - Garantir imutabilidade em campos críticos com
readonly.
🛠️ Passo a Passo
1. Definição das Interfaces
interface IUser {
readonly id: number;
nome: string;
email: string;
}
interface ITask {
titulo: string;
descricao?: string;
concluida: boolean;
responsavel: IUser;
}
interface IProject {
nome: string;
tarefas: ITask[];
}
2. Implementação
Crie uma função que receba um IProject e retorne apenas as tarefas concluídas.
const meuProjeto: IProject = {
nome: "Refatoração TS",
tarefas: [
{ titulo: "Setup", concluida: true, responsavel: { id: 1, nome: "R", email: "r@b.com" } },
{ titulo: "Build", concluida: false, responsavel: { id: 1, nome: "R", email: "r@b.com" } }
]
};
function listarConcluidas(projeto: IProject): ITask[] {
return projeto.tarefas.filter(t => t.concluida);
}
✅ Desafio Extra
- Crie uma interface
ITaskUrgenteque estendeITaske adiciona um campoprazo: Date. - Use
Declaration Mergingpara adicionar uma propriedadeavatarna interfaceIUser.
Mini-Projeto: Aula 05 – Sistema Bancário (Classes e POO) 🏦
Objetivo
Aplicar os conceitos de Programação Orientada a Objetos (Classes, Modificadores de Acesso, Herança) para criar um sistema de gerenciamento de contas bancárias.
🏗️ Requisitos do Projeto
- Classe base
Contacom atributos privados. - Uso de
protectedpara permitir herança. - Subclasses
ContaCorrenteeContaPoupancacom regras específicas. - Implementação de getters e setters para validação de saldo.
🛠️ Passo a Passo
1. Classe Base
abstract class Conta {
constructor(
private _titular: string,
protected _saldo: number = 0
) {}
get saldo() { return this._saldo; }
depositar(valor: number): void {
if (valor > 0) this._saldo += valor;
}
abstract sacar(valor: number): boolean;
}
2. Extensões
class ContaCorrente extends Conta {
sacar(valor: number): boolean {
if (valor <= this._saldo + 100) { // Limite extra
this._saldo -= valor;
return true;
}
return false;
}
}
class ContaPoupanca extends Conta {
sacar(valor: number): boolean {
if (valor <= this._saldo) {
this._saldo -= valor;
return true;
}
return false;
}
}
✅ Desafio Extra
- Crie uma classe
Bancoque armazena um array deContae possui um método para listar todos os titulares e seus saldos (Polimorfismo). - Adicione uma propriedade
readonlychamadanumeroContagerada automaticamente no construtor.
Mini-Projeto: Aula 06 – Repositório de Dados Genérico (Generics) 📦
Objetivo
Criar uma estrutura de dados genérica e reutilizável que possa gerenciar qualquer tipo de entidade (Usuários, Produtos, etc.) mantendo a tipagem original.
🏗️ Requisitos do Projeto
- Classe genérica
Repository<T>. - Restrição (
Constraints) para garantir que as entidades possuam umid. - Métodos para Adicionar, Listar, Buscar por ID e Remover.
🛠️ Passo a Passo
1. Interface de Entidade
2. Classe Repositório
class Repository<T extends Entity> {
private data: T[] = [];
add(item: T): void {
this.data.push(item);
}
getAll(): T[] {
return this.data;
}
findById(id: number | string): T | undefined {
return this.data.find(item => item.id === id);
}
remove(id: number | string): void {
this.data = this.data.filter(item => item.id !== id);
}
}
✅ Desafio Extra
- Crie uma interface
Usere umaProducte instancie repositórios específicos para cada uma:const userRepo = new Repository<User>(). - Implemente um método
update(id, item)que atualize os dados de uma entidade sem mudar seuid.
Mini-Projeto: Aula 07 – Formulário de Perfil (Utility Types) ⚙️
Objetivo
Utilizar utilitários como Partial, Readonly, Pick e Omit para gerenciar diferentes estados de um perfil de usuário em uma aplicação.
🏗️ Requisitos do Projeto
- Interface completa de
UserProfile. - Criar um tipo para "Visualização Pública" (omitindo dados sensíveis).
- Criar um tipo para "Atualização de Perfil" (permitindo campos parciais).
- Garantir que o ID do usuário seja imutável.
🛠️ Passo a Passo
1. Modelo Base
interface UserProfile {
id: number;
nome: string;
email: string;
telefone?: string;
senhaHash: string;
dataCriacao: Date;
}
2. Uso de Utility Types
// Apenas o que o usuário pode ver de outros
type PublicProfile = Omit<UserProfile, "senhaHash" | "email">;
// O que enviamos para o banco ao atualizar (ID obrigatório, resto parcial)
type UpdatePayload = Partial<Omit<UserProfile, "id" | "dataCriacao">> & { id: number };
// Usuário imutável após carregado
type SecureUser = Readonly<UserProfile>;
✅ Desafio Extra
- Use
Pickpara criar um tipoUserContactque contenha apenasnomeeemail. - Use
Recordpara criar um objeto que mapeieiddo usuário para seuPublicProfile.
Mini-Projeto: Aula 08 – Dinamismo com Tipos (Advanced Manipulation) 🧪
Objetivo
Explorar propriedades dinâmicas usando keyof, Mapped Types e Template Literals para criar um sistema de notificações inteligente.
🏗️ Requisitos do Projeto
- Usar
keyofpara criar um sistema de acesso seguro a chaves. - Template Literals para gerar nomes de manipuladores de eventos.
- Criar tipos que se adaptam dinamicamente a modelos de dados.
🛠️ Passo a Passo
1. Acesso Dinâmico Seguro
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const config = { porta: 3000, host: "localhost" };
const p = getProp(config, "porta"); // OK e Tipado!
2. Sistema de Eventos Literais
type Eventos = "focus" | "blur" | "click";
type EventHandlers = {
[K in Eventos as `on${Capitalize<K>}`]: () => void;
};
const handlers: EventHandlers = {
onFocus: () => console.log("Focado"),
onBlur: () => {},
onClick: () => {}
};
✅ Desafio Extra
- Crie um
Mapped Typeque transforme todas as propriedades de um objeto em funções que retornam aquele tipo (Getters). - Use
Conditional Typespara criar um utilitário que remova a propriedade "id" de qualquer tipo de objeto passado.
Mini-Projeto: Aula 09 – Biblioteca Modular (Organização de Projeto) 📁
Objetivo
Organizar um sistema de gerenciamento de livros em uma estrutura modular profissional, utilizando ES Modules, Barrel Files e Path Aliases.
🏗️ Requisitos do Projeto
- Dividir o código em pastas:
models,serviceseapp. - Usar
index.tspara centralizar as exportações de cada pasta. - Configurar e usar um path alias
@corepara o diretório de modelos.
🛠️ Passo a Passo
1. Estrutura de Pastas
Crie a seguinte hierarquia:
src/
├── models/
│ ├── Livro.ts
│ └── index.ts
├── services/
│ ├── Biblioteca.ts
│ └── index.ts
└── index.ts
2. Barrel File em models
No arquivo src/models/index.ts:
3. Configurando o Alias no tsconfig.json
✅ Verificação Final
- Importe o modelo
LivroemBiblioteca.tsusando o alias:import { Livro } from '@core';. - Certifique-se de que o arquivo principal (
src/index.ts) importa apenas do serviço e executa uma lógica de teste (ex: adicionar um livro e listar).
Mini-Projeto: Aula 10 – API de Tarefas (Backend com Node.js) 🟢
Objetivo
Construir uma API REST funcional para gerenciamento de tarefas utilizando Node.js, Express e TypeScript, focando na tipagem de Request/Response e uso de DTOs.
🏗️ Requisitos do Projeto
- Criar rotas para: Listar, Criar e Deletar tarefas.
- Tipar rigorosamente o corpo da requisição (
JSON Body). - Implementar um middleware simples de log.
- Usar uma estrutura de "Base de Dados" em memória (Array tipado).
🛠️ Passo a Passo
1. Servidor Básico
import express, { Request, Response } from 'express';
const app = express();
app.use(express.json());
interface Tarefa {
id: number;
titulo: string;
feita: boolean;
}
const db: Tarefa[] = [];
2. Rotas Tipadas
app.get('/tarefas', (req: Request, res: Response) => {
res.json(db);
});
app.post('/tarefas', (req: Request<{}, {}, Omit<Tarefa, 'id'>>, res: Response) => {
const nova: Tarefa = { id: Date.now(), ...req.body };
db.push(nova);
res.status(201).json(nova);
});
✅ Desafio Extra
- Crie um middleware que verifique se o campo
tituloestá presente no corpo da requisição antes de passar para a rota de criação. - Implemente a rota
DELETE /tarefas/:idtratando o parâmetroidde forma tipada.
Mini-Projeto: Aula 11 – Dashboard de Usuários (Frontend React) ⚛️
Objetivo
Desenvolver uma interface simples em React com TypeScript para listar e adicionar usuários, focando na tipagem de Props, Hooks e Eventos.
🏗️ Requisitos do Projeto
- Componente
UserCardtipado. - Formulário para adicionar novos usuários.
- Uso de
useStatecom interface genérica. - Tipagem de eventos de clique e mudança de input.
🛠️ Passo a Passo
1. Definição da Interface
2. Componente de Lista
const UserList = () => {
const [users, setUsers] = useState<User[]>([]);
const addUser = (nome: string) => {
const newUser = { id: Date.now(), nome, cargo: "Dev" };
setUsers([...users, newUser]);
};
return (
<div>
{users.map(u => <UserCard key={u.id} user={u} />)}
<Form onAdd={addUser} />
</div>
);
};
✅ Desafio Extra
- Crie um
Context APIpara gerenciar o tema da aplicação (Light/Dark) e garanta que o provedor e o hookuseThemeestejam 100% tipados. - Tipar o evento do formulário para evitar o recarregamento da página (
e.preventDefault()).
Mini-Projeto: Aula 12 – Buscador de Repositórios (Integração API) 📡
Objetivo
Consumir a API pública do GitHub para buscar repositórios de um usuário, aplicando tipagem de dados externos, tratamento de erros e validação com Zod.
🏗️ Requisitos do Projeto
- Usar
Axiospara realizar as chamadas HTTP. - Definir interfaces para a resposta do GitHub.
- Validar os dados recebidos com um schema
Zod. - Implementar tratamento de erro para usuários não encontrados.
🛠️ Passo a Passo
1. Schema de Validação (Zod)
import { z } from 'zod';
const RepoSchema = z.object({
name: z.string(),
description: z.string().nullable(),
stargazers_count: z.number(),
html_url: z.string().url()
});
type Repo = z.infer<typeof RepoSchema>;
2. Chamada de API com Axios
async function getRepos(user: string): Promise<Repo[]> {
const { data } = await axios.get<Repo[]>(`https://api.github.com/users/${user}/repos`);
// Validar cada repositório da lista
return data.map(r => RepoSchema.parse(r));
}
✅ Desafio Extra
- Crie uma função "Mapper" que transforme as chaves vindas do GitHub (ex:
stargazers_count) para nomes mais amigáveis no seu código (ex:estrelas). - Exiba uma mensagem de erro customizada caso a API retorne um erro 404 (Usuário não encontrado).
Mini-Projeto: Aula 13 – Testando um Carrinho de Compras (Testes) 🧪
Objetivo
Implementar uma suíte de testes unitários para um sistema de carrinho de compras, utilizando Jest e TypeScript para garantir que cálculos de totais e descontos estejam corretos.
🏗️ Requisitos do Projeto
- Classe
Carrinhocom métodos:adicionar,removerecalcularTotal. - Testar se o carrinho inicia vazio.
- Testar se o total é calculado corretamente após adições.
- Mockar um "Serviço de Frete" para testar o total com entrega.
🛠️ Passo a Passo
1. Classe a ser Testada
export class Carrinho {
private itens: { nome: string, preco: number }[] = [];
adicionar(item: { nome: string, preco: number }) {
this.itens.push(item);
}
getTotal(): number {
return this.itens.reduce((acc, curr) => acc + curr.preco, 0);
}
}
2. Arquivo de Teste (.spec.ts)
import { Carrinho } from './Carrinho';
describe('Carrinho de Compras', () => {
it('deve calcular o total corretamente', () => {
const c = new Carrinho();
c.adicionar({ nome: 'Livro', preco: 50 });
c.adicionar({ nome: 'Mouse', preco: 100 });
expect(c.getTotal()).toBe(150);
});
});
✅ Desafio Extra
- Implemente um teste para verificar se o método
remover(nome)funciona conforme o esperado. - Adicione um teste que valide uma mensagem de erro caso tentemos adicionar um item com preço negativo.
- Configure o Jest para exibir o relatório de cobertura (
coverage) ao rodar os testes.
Mini-Projeto: Aula 14 – Gateway de Pagamentos (Design Patterns) 🛡️
Objetivo
Aplicar o padrão Strategy e Repository para criar um sistema de processamento de pagamentos flexível (Cartão, Boleto, Pix) sem acoplamento.
🏗️ Requisitos do Projeto
- Interface
IPaymentStrategy. - Implementações para
CreditCardPaymentePixPayment. - Classe
PaymentContextque executa a estratégia selecionada. - Uso de
Dependency Injectionpara passar a estratégia desejada.
🛠️ Passo a Passo
1. O Padrão Strategy
interface IPaymentStrategy {
process(amount: number): string;
}
class PixPayment implements IPaymentStrategy {
process(amount: number) { return `Pix de R$${amount} gerado.`; }
}
class CardPayment implements IPaymentStrategy {
process(amount: number) { return `Cartão de R$${amount} processado.`; }
}
2. O Contexto
class Checkout {
constructor(private strategy: IPaymentStrategy) {}
finalizar(valor: number) {
console.log(this.strategy.process(valor));
}
}
const pedido = new Checkout(new PixPayment());
pedido.finalizar(200);
✅ Desafio Extra
- Implemente o padrão
Factorypara instanciar a estratégia correta baseada em uma string (ex: "PIX", "CARD"). - Crie um
Repository(interface + implementação em memória) para salvar o histórico de pagamentos realizados.
Mini-Projeto: Aula 15 – Refatorando para Clean Code (Arquitetura) 📐
Objetivo
Transformar um código funcional, porém "sujo" (com funções gigantes e múltiplas responsabilidades), em um sistema seguindo os princípios SOLID e Clean Code.
🏗️ Requisitos do Projeto
- Dividir uma função "faz-tudo" em funções menores e específicas.
- Aplicar nomes significativos em variáveis e tipos.
- Isolar a lógica de negócio de efeitos colaterais (log, persistência).
- Garantir que cada classe tenha apenas uma responsabilidade (SRP).
🛠️ Passo a Passo
1. O Código Sujo (Antes)
Analise este código que calcula desconto, salva no banco e envia email de uma vez:
async function processar(pedido: any) {
let total = 0;
for(let i of pedido) { total += i.preco; }
if (total > 100) total *= 0.9;
await db.save(pedido, total);
await email.send("Pedido feito");
}
2. O Código Limpo (Depois)
Separe em classes e métodos:
- OrderScanner: Para somar os itens.
- DiscountService: Para aplicar regras de negócio.
- NotificationService: Para envio de avisos.
✅ Desafio Extra
- Aplique o Princípio da Inversão de Dependência (D do SOLID) no
NotificationService, permitindo trocarEmailporWhatsAppatravés de uma interface comum. - Implemente validações robustas que lancem exceções customizadas em vez de apenas retornar
null.
Projeto Final: Aula 16 – Aplicação Fullstack e Deploy 🚀
Objetivo
O desafio final! Integrar todos os conhecimentos do curso para criar uma aplicação completa (Node + React + TS), containerizar com Docker e preparar para o Deploy.
🏗️ Requisitos do Projeto
- Backend: API de catálogo de produtos com Node e Express.
- Frontend: Dashboard para visualização e compra via React.
- Integração: Consumo da API própria usando Axios e Zod.
- Docker: Criar um
Dockerfilefuncional. - Build: Scripts de build para produção ativos.
🛠️ Etapas de Execução
1. Desenvolvimento Integrado
- Aplique Interfaces e Shared Types entre os projetos.
- Utilize Design Patterns (Repository/Service) no Backend.
- Garanta Testes Unitários no núcleo da aplicação.
2. Preparação para Produção
No package.json:
3. Containerização (Docker)
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
✅ Critérios de Sucesso
- [ ] A aplicação roda localmente via
npm run dev. - [ ] O build de produção é gerado sem erros de tipagem.
- [ ] A imagem Docker é construída com sucesso.
- [ ] Existe uma documentação (
README.md) explicando como rodar o projeto.
🚀 Rumo ao Deploy!
Parabéns por chegar até aqui. Sua aplicação está pronta para o mundo real!
Quizzes
Quizzes Interativos 🧠
Avalie sua retenção de conhecimento após cada aula do curso TypeScript Profissional.
-
Módulo 1: Core & Linguagem
-
Módulo 2: Ecossistema & Apps
Quiz 01 - Introdução
Quiz 02 - Introdução
Quiz 03 - Introdução
Quiz 04 - Introdução
Quiz 05 - Introdução
Quiz 06 - Introdução
Quiz 07 - Introdução
Quiz 08 - Introdução
Quiz 09 - Introdução
Quiz 10 - Introdução
Quiz 11 - Introdução
Quiz 12 - Introdução
Quiz 13 - Introdução
Quiz 14 - Introdução
Quiz 15 - Introdução
Quiz 16 - Introdução
Slides
Slides de Apoio 📽️
Material visual utilizado durante as aulas teóricas do curso.
-
Módulo 1: Core & Linguagem
-
Módulo 2: Ecossistema & Apps
Conteúdo do Curso
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Conteúdo do Curso.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Introdução à Programação
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Introdução à Programação.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Estrutura Sequencial
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Estrutura Sequencial.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Estrutura Condicional
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Estrutura Condicional.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Estruturas Repetitivas
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Estruturas Repetitivas.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Vetores
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Vetores.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Matrizes
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Matrizes.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Funções
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Funções.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem C
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem C.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem C++
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem C++.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem Java
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem Java.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem C
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem C#.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem Python
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem Python.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem JavaScript
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem JavaScript.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem Rust
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem Rust.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Linguagem Dart
Tópicos da Aula
- Introdução ao tema
- Conceitos fundamentais
- Exemplos práticos
- Exercícios de fixação
Conceito Chave
Definição importante sobre Linguagem Dart.
Exemplo Prático
Conclusão
- Resumo do que aprendemos
- Próximos passos
Configuração
Guias de Instalação 🛠️
Prepare seu ambiente de desenvolvimento.
-
Ferramentas Iniciais
Comece por aqui.
-
Linguagens Corporativas
Para grandes sistemas.
-
Sistemas e Mobile
Performance e Apps.
Setup 01: Ferramentas de Lógica 🧩
Neste guia, você aprenderá a preparar o ambiente para praticar Lógica de Programação.
1. VisualG (Pseudocódigo)
O VisualG é a ferramenta mais leve para iniciar.
* Download: Baixe em visualg3.com.br.
* Instalação: Não precisa instalar. Apenas extraia o .zip e execute o visualg30.exe.
* Teste: Escreva um algoritmo simples e aperte F9 para rodar.
2. Portugol Studio
Uma alternativa mais moderna e bonita ao VisualG. * Download: Baixe em univali.br. * Instalação: Siga o instalador padrão (Windows/Linux/Mac).
3. Scratch (Lógica em Blocos)
- Acesso: Apenas acesse scratch.mit.edu.
- Uso: Arraste os blocos para a área central e clique na bandeira verde.
4. Fluxogramas (Draw.io)
Para desenhar fluxogramas e UML. * Acesso: diagrams.net. * Uso: Selecione "Flowchart" na barra lateral e arraste as formas.
5. Excel (Lógica de Tabela)
O Excel é excelente para entender tabelas (Matrizes) e fórmulas (Funções). * Alternativa Gratuita: Google Sheets ou LibreOffice Calc.
6. Solução de Problemas Comuns ⚠️
- VisualG travando: Execute como Administrador (botão direito -> Executar como admin).
- Antivírus bloqueou: O VisualG é antigo e alguns antivírus acham que é ameaça. Adicione nas exceções.
- Portugol Studio não abre: Verifique se você tem o Java instalado (ele depende do Java).
Setup 02: C e C++ 🚀
Opção 1: Code::Blocks (Mais Fácil)
Ideal para iniciantes, pois já vem com tudo configurado.
1. Acesse codeblocks.org.
2. Baixe a versão que tem mingw-setup.exe no nome (ex: codeblocks-20.03mingw-setup.exe).
3. Instale e execute. Ele deve detectar o compilador automaticamente.
Opção 2: VS Code + MinGW (Profissional)
- Baixe o MinGW-w64: sourceforge.net/projects/mingw-w64/.
- Extraia e coloque a pasta na raiz
C:\mingw64. - Variáveis de Ambiente:
- Pesquise "Variáveis de Ambiente" no Windows.
- Edite o
Pathe adicioneC:\mingw64\bin.
- VS Code: Instale a extensão "C/C++" da Microsoft.
4. Solução de Problemas Comuns ⚠️
- 'gcc' não é reconhecido: Você esqueceu de adicionar a pasta
bindo MinGW ao PATH do Windows. Revise o passo 1. - Erro ao compilar: Certifique-se de que salvou o arquivo com a extensão
.c(para C) ou.cpp(para C++). - Terminal fecha rápido: Adicione
getchar();ousystem("pause");antes doreturn 0;para segurar a tela.
Setup 03: Web Moderno (JS/TS) 🌐
1. Node.js
O motor que roda JavaScript fora do navegador.
1. Baixe a versão LTS em nodejs.org.
2. Instale (Next, Next, Finish).
3. Teste no terminal: node -v e npm -v.
2. Visual Studio Code
O editor padrão da indústria. 1. Baixe em code.visualstudio.com. 2. Instale extensões úteis: * Live Server: Para rodar HTML localmente. * Prettier: Para formatar código. * ESLint: Para encontrar erros.
3. TypeScript
Após instalar o Node.js, instale o compilador TS globalmente:
Teste comtsc -v.
4. Solução de Problemas Comuns ⚠️
- cmd 'node' não encontrado: Reinicie seu terminal ou computador após instalar o Node.js.
- Erro de Permissão no npm: Tente executar o terminal como Administrador ou use o
nvmpara gerenciar versões. - Code Runner não funciona: Verifique se o Node está no PATH. Tente rodar manualmente no terminal:
node arquivo.js.
Setup 04: Java e JDK ☕
1. JDK (Java Development Kit)
O kit essencial para compilar Java.
1. Baixe o JDK 17 LTS (ou 21 LTS) no site da Oracle ou Adoptium.
2. Instale e configure a variável de ambiente JAVA_HOME.
3. Teste: java -version.
2. IntelliJ IDEA (Recomendado)
A melhor IDE para Java/Kotlin. 1. Baixe a versão Community (Gratuita) em jetbrains.com/idea. 2. Instale.
3. VS Code
Se preferir o VS Code: 1. Instale o "Extension Pack for Java" da Microsoft.
4. Solução de Problemas Comuns ⚠️
- 'javac' não reconhecido: A variável de ambiente
JAVA_HOMEou oPathestão errados. Verifique se apontam para a pastabindo JDK. - Erro: "Class names are only accepted...": O nome do arquivo DEVE ser igual ao nome da classe (ex:
Ola.javatem que terpublic class Ola). - Versão antiga do Java: Digite
java -versionpara conferir se está usando a versão que acabou de instalar.
Setup 05: .NET (C# e F#) 🔷
1. .NET SDK
Necessário para rodar C# e F#.
1. Baixe o .NET 8.0 SDK (LTS) em dotnet.microsoft.com.
2. Instale.
3. Teste: dotnet --version.
2. Visual Studio Community
A IDE mais completa para Windows. 1. Baixe em visualstudio.microsoft.com. 2. No instalador, selecione a carga de trabalho: "Desenvolvimento para desktop com .NET".
3. VS Code + C# Dev Kit
Para uma experiência mais leve: 1. Instale a extensão "C# Dev Kit" da Microsoft.
4. Solução de Problemas Comuns ⚠️
- 'dotnet' não encontrado: Reinicie o computador após instalar o SDK.
- Erro de Certificado HTTPS: Na primeira execução, rode
dotnet dev-certs https --trustpara confiar no certificado local. - OmniSharp Error: Se o VS Code reclamar, verifique se instalou o C# Dev Kit e se o SDK é compatível.
Setup 06: Python 🐍
1. Interpretador Python
- Baixe a versão mais recente em python.org.
- IMPORTANTE: Marque a caixa "Add Python to PATH" na instalação!
- Teste:
python --versionoupy --version.
2. PyCharm Community
A IDE mais poderosa para Python. 1. Baixe em jetbrains.com/pycharm.
3. VS Code + Python
- Instale a extensão "Python" da Microsoft.
- Instale a extensão "Jupyter" se quiser usar Notebooks.
4. Solução de Problemas Comuns ⚠️
- 'python' não encontrado: É o erro mais comum. Reinstale e marque a caixa "Add Python to PATH".
- Comando 'python' abre a Microsoft Store: Vá nas configurações do Windows ("Gerenciar Aliases de Execução de Aplicativo") e DESATIVE os itens do "Instalador de Aplicativo" para Python.
- Pip não funciona: Tente
python -m pip install pacote.
Setup 07: Sistemas (Rust e Go) ⚙️
Rust 🦀
O Rust usa o gerenciador rustup.
1. Acesse rustup.rs.
2. Baixe e execute o rustup-init.
3. Aceite o padrão (opção 1).
4. Reinicie o terminal e teste: cargo --version.
5. VS Code: Instale a extensão "rust-analyzer".
Go (Golang) 🐹
- Baixe em go.dev.
- Instale (Next, Next, Finish).
- Teste:
go version. - VS Code: Instale a extensão "Go" oficial.
4. Solução de Problemas Comuns ⚠️
- 'cargo' não encontrado: Reinicie o terminal. Se não funcionar, adicione
~/.cargo/bin(Linux/Mac) ou%USERPROFILE%\.cargo\bin(Windows) ao PATH. - Go Path: Certifique-se de que a variável
GOPATHestá configurada corretamente (geralmenteC:\Users\SeuUsuario\go). - Erro de Linker (Rust): No Windows, pode faltar as ferramentas de build do C++. Baixe o "Build Tools for Visual Studio".
Setup 08: Mobile (Flutter e Kotlin) 📱
Desenvolvimento mobile exige ferramentas mais pesadas.
1. Android Studio
Essencial para emular celulares Android e programar em Kotlin/Java nativo. 1. Baixe em developer.android.com/studio. 2. Instale e deixe ele baixar o Android SDK.
2. Flutter SDK
Para desenvolvimento Dart multiplataforma.
1. Baixe o SDK em flutter.dev.
2. Extraia para C:\src\flutter (exemplo).
3. Adicione C:\src\flutter\bin ao Path do Windows.
4. Rode flutter doctor no terminal para verificar o que falta.
3. VS Code
O editor preferido para Flutter. 1. Instale a extensão "Flutter" (ela instala a do Dart automaticamente).
4. Solução de Problemas Comuns ⚠️
- flutter doctor com erros: É normal. Siga o que ele diz. Geralmente é aceitar licenças (
flutter doctor --android-licenses). - Emulador não abre (HAXM/Hyper-V): Seu processador precisa ter virtualização ativada na BIOS.
- Gradle demorando: A primeira vez demora MUITO (baixa a internet inteira). Tenha paciência.
Setup 09: PHP e Servidor Local 🐘
Como o PHP roda no servidor, precisamos simular um servidor no nosso computador.
1. XAMPP (Tudo em Um)
O pacote mais fácil. Inclui Apache (Servidor), MySQL (Banco) e PHP.
1. Baixe em apachefriends.org.
2. Instale e abra o XAMPP Control Panel.
3. Clique em Start no Apache e MySQL.
4. Seus arquivos devem ficar na pasta C:\xampp\htdocs.
2. Composer (Gerenciador de Pacotes)
Essencial para usar bibliotecas modernas e frameworks como Laravel. 1. Baixe em getcomposer.org. 2. Instale. Ele deve encontrar seu PHP automaticamente.
3. Laravel (Opcional)
Para criar projetos profissionais:
4. Solução de Problemas Comuns ⚠️
- Apache não inicia (Port 80 busy): Skype ou IIS podem estar usando a porta 80. No XAMPP, vá em Config -> httpd.conf e mude
Listen 80paraListen 8080. - MySQL não conecta: Verifique se o serviço está verde no XAMPP.
- Erro de DLL: Pode faltar o "Visual C++ Redistributable" no seu Windows. Atualize-o.
Sobre
Sobre o Curso
🎓 TypeScript Profissional: Do Core à Arquitetura
Este é um curso completo e estruturado para quem deseja dominar o TypeScript no cenário real do desenvolvimento moderno. Projetado para levar você do setup básico em Node.js até a construção de aplicações complexas com React, APIs robustas e arquiteturas escaláveis.
🎯 Objetivos do Curso
-
Domínio Técnico
Aprender não apenas a sintaxe, mas o "pensamento tipado" (Type Thinking) para modelar sistemas seguros.
-
Ecossistema Real
Integrar TypeScript com as ferramentas mais usadas no mercado: Express, React, Zod, Jest e Docker.
-
Qualidade de Software
Aplicar princípios de Clean Code, SOLID e Design Patterns para criar códigos fáceis de manter por equipes.
-
Engenharia de Dados
Dominar Generics, Tipos Avançados e Manipulação de Dados Externos com total segurança e previsibilidade.
📚 O Que Você Vai Aprender
Módulo 1 – Core & Linguagem
- Setup Profissional e Compilação
- Tipos Primitivos, Avançados e Inferência
- Interfaces vs Type Aliases
- Classes, POO e Modificadores de Acesso
- Generics e Utility Types
- Manipulação Dinâmica de Tipos
Módulo 2 – Ecossistema & Arquitetura
- Organização em Módulos e Aliases
- Backend com Node.js e Express
- Frontend Moderno com React
- Integração de APIs e Validação (Zod)
- Testes Automatizados com Jest
- Padrões de Projeto e Clean Code
- Build para Produção e Docker
🛠️ Metodologia
-
Aulas Práticas
Conteúdo focado em cenários de código real, com diagramas Mermaid para facilitar a compreensão.
-
80 Exercícios
Listas graduadas (Básico, Médio, Desafio) para fixar cada conceito da linguagem.
-
16 Mini-Projetos
Saia da aula com algo pronto: desde calculadoras tipadas até APIs e Dashboards completos.
-
Quizzes Detalhados
Avalie seu progresso com 160 questões comentadas em português.
👨🎓 Para Quem é Este Curso
- Desenvolvedores JS que querem evitar bugs e subir de nível profissional
- Estudantes que buscam uma base sólida de Engenharia de Software
- Profissionais que pretendem trabalhar em grandes empresas de tecnologia
- Arquitetos de Software que precisam padronizar códigos escaláveis
📋 Pré-requisitos
- Conhecimento básico de lógica e JavaScript
- Node.js instalado (coberto no curso)
- Editor de código (VS Code recomendado)
- Vontade de escrever código de alta qualidade!
🎖️ O Que Você Receberá
- ✅ 16 aulas completas e atualizadas
- ✅ Slides interativos para todas as aulas
- ✅ 80 exercícios práticos com soluções
- ✅ 16 mini-projetos para portfólio
- ✅ 160 questões de quiz com explicações
- ✅ Guia de Deploy e Dockerização
🚀 Comece Agora
Pronto para dominar o TypeScript?
Dúvidas? Explore o Roadmap do Projeto ou comece agora mesmo!
Roadmap do Projeto: TypeScript Profissional
Este documento rastreia o progresso do desenvolvimento do curso "TypeScript Profissional: Do Core à Arquitetura".
✅ Fase 1: Estruturação e Core (Concluído)
- [x] Definição do novo currículo focado em TypeScript Profissional.
- [x] Refatoração completa das 16 aulas teóricas.
- [x] Implementação de 80 exercícios práticos (5 por aula).
- [x] Criação de 160 questões de quiz com explicações detalhadas.
✅ Fase 2: Aplicações e Slides (Concluído)
- [x] Geração de slides profissionais com Reveal.js (20+ por aula).
- [x] Criação de 16 mini-projetos aplicados.
- [x] Padronização visual com Mermaid.js e Admonitions.
🚧 Fase 3: Refino Técnico e Visual (Em Andamento)
- [ ] Otimização de sintaxe nos slides.
- [ ] Verificação de acessibilidade e responsividade.
- [ ] Padronização de espaçamentos e blocos de código.
🚀 Fase 4: Deploy e Qualidade
- [x] Configuração centralizada no
mkdocs.yml. - [ ] Execução de build estrito (
--strict). - [ ] Lançamento final no GitHub Pages.
Status Atual: Fase 3 - Refino e Qualidade. Última Atualização: 22/02/2026
Materiais
Bem-vindo à seção de materiais complementares do curso. Aqui você encontra recursos adicionais para apoiar seus estudos.
-
- Acesse os slides de todas as aulas para revisão.
-
- Pratique com listas de exercícios para cada módulo.
-
- Teste seus conhecimentos com quizzes interativos.
-
- Desenvolva projetos práticos para aplicar o que aprendeu.
-
- Guias de instalação e configuração do ambiente.
Versão para Impressão
Esta página foi gerada automaticamente para impressão.