# Aula 3.1 - Introdução ao TypeScript

## Identificação

- **Duração:** 2 horas
- **Tipo:** teoria aplicada e laboratório
- **Entrega:** primeiro projeto tipado
- **Laboratório:** [`../exemplos/aula-3.1/index.html`](../exemplos/aula-3.1/index.html)

## Introdução

### O que é TypeScript?

TypeScript é uma linguagem construída sobre JavaScript. Ela adiciona um sistema de
tipos estáticos e ferramentas de análise:

```ts
const courseName: string = "Engenharia de IA";
const completedLessons: number = 8;
```

Todo JavaScript válido é, em termos gerais, ponto de partida para TypeScript. O
TypeScript analisa o código antes da execução e ajuda a encontrar inconsistências.

### TypeScript substitui JavaScript?

Não. O navegador executa JavaScript. O código TypeScript normalmente passa por um
compilador ou ferramenta de compilação que remove os tipos e gera JavaScript:

```text
app.ts → compilador TypeScript → app.js → navegador
```

Aprender TypeScript não elimina a necessidade de compreender JavaScript. Condições,
funções, arrays, objetos, Promises e o DOM continuam sendo JavaScript.

### TypeScript é framework?

Não. TypeScript é uma linguagem e um conjunto de ferramentas. Angular é um
framework que utiliza TypeScript, mas TypeScript pode ser usado sem Angular.

### O que significa tipagem estática?

Significa que o código pode ser analisado antes de executar:

```ts
let estimate: number = 2;
estimate = "duas horas";
```

O compilador sinaliza que uma string não pode ser atribuída a `number`.

JavaScript continua tendo tipos em execução, mas eles pertencem aos valores e podem
mudar dinamicamente. TypeScript adiciona contratos verificados durante o
desenvolvimento.

### TypeScript impede todos os erros?

Não. Ele ajuda a detectar uma classe importante de problemas, mas não prova que
todo comportamento está correto:

```ts
function divide(a: number, b: number): number {
  return a / b;
}

divide(10, 0); // permitido pelo tipo, mas exige regra de negócio
```

Também não substitui testes, validação, segurança, revisão ou observabilidade.

### Os tipos existem no navegador?

Normalmente, não. Eles são removidos na compilação:

```ts
const estimate: number = 2;
```

JavaScript gerado:

```js
const estimate = 2;
```

Isso é chamado de **apagamento de tipos**.

### TypeScript valida JSON de uma API?

Não automaticamente:

```ts
const response = await fetch("/api/tasks");
const data = await response.json();
```

O servidor pode enviar um formato diferente do tipo declarado. Dados externos
precisam ser validados em tempo de execução.

### Onde isso aparece no projeto?

O laboratório mostrará lado a lado o contrato TypeScript e o JavaScript executado.
Um formulário demonstrará que HTML fornece strings e que conversão e validação
continuam necessárias.

## Objetivos

Ao final da aula, o aluno deverá conseguir:

1. explicar o papel do TypeScript;
2. diferenciar TypeScript, JavaScript e framework;
3. descrever compilação e apagamento de tipos;
4. diferenciar erro estático e erro em execução;
5. utilizar inferência e anotações;
6. tipar primitivas, arrays, objetos e funções;
7. reconhecer `any` e `unknown`;
8. entender que tipos não validam dados externos;
9. ler uma configuração TypeScript básica;
10. relacionar código `.ts` à saída `.js`.

## Pré-requisitos

- Módulos 1 e 2 concluídos;
- JavaScript moderno, módulos e testes;
- editor de código;
- Node.js e npm serão utilizados nas próximas etapas de configuração.

## Pergunta orientadora

> Como detectar incompatibilidades antes de executar sem confundir tipos estáticos com validação real dos dados?

## Roteiro sugerido

| Etapa | Duração |
|---|---:|
| TypeScript, JavaScript e compilação | 20 min |
| Inferência e anotações | 25 min |
| Arrays, objetos e funções | 30 min |
| `any`, `unknown` e dados externos | 20 min |
| Laboratório | 20 min |
| Revisão | 5 min |

## 1. Extensões de arquivo

- `.js`: JavaScript;
- `.ts`: TypeScript;
- `.tsx`: TypeScript com sintaxe JSX, comum em algumas bibliotecas de interface;
- `.d.ts`: declarações de tipos.

Nosso primeiro arquivo será `app.ts`.

## 2. Anotação de tipo

```ts
const title: string = "Estudar TypeScript";
let estimate: number = 2;
let completed: boolean = false;
```

A anotação aparece depois do nome.

Evite tipos escritos como construtores:

```ts
const title: String = "texto";
```

Prefira primitivas em minúsculas:

```ts
const title: string = "texto";
```

## 3. Inferência

TypeScript frequentemente deduz o tipo:

```ts
const title = "Estudar TypeScript";
let estimate = 2;
```

Não é necessário anotar tudo. Use anotações quando:

- o contrato público precisa ficar explícito;
- o tipo não pode ser inferido corretamente;
- declaramos parâmetros;
- queremos impedir uma inferência estreita ou ampla demais;
- a anotação melhora a compreensão.

## 4. `const` e tipos literais

```ts
const status = "todo";
```

Como a constante não será reatribuída, TypeScript pode inferir o literal `"todo"`,
não apenas `string`.

Com `let`:

```ts
let status = "todo";
```

O tipo normalmente é ampliado para `string`, pois outros textos podem ser
atribuídos.

## 5. Tipos primitivos

```ts
const title: string = "Tarefa";
const estimate: number = 3;
const completed: boolean = false;
const identifier: bigint = 10n;
const token: symbol = Symbol("token");
```

`null` e `undefined` possuem tipos próprios. Com configuração estrita, precisam ser
tratados explicitamente.

## 6. Arrays

```ts
const tags: string[] = ["typescript", "curso"];
const estimates: Array<number> = [1, 2, 3];
```

As duas formas são equivalentes. `string[]` costuma ser mais compacta.

Este array rejeita números:

```ts
tags.push(42);
```

## 7. Objetos

Tipo escrito diretamente:

```ts
const task: {
  id: number;
  title: string;
  completed: boolean;
} = {
  id: 1,
  title: "Estudar",
  completed: false,
};
```

Interfaces e aliases evitam repetir essa estrutura e serão aprofundados na Aula
3.2.

## 8. Propriedade opcional

```ts
const task: {
  title: string;
  description?: string;
} = {
  title: "Estudar",
};
```

`description?` pode estar ausente. Ao acessar, o tipo inclui `undefined`.

Opcional não significa automaticamente `null`.

## 9. Funções

```ts
function normalizeTitle(value: string): string {
  return value.trim().replaceAll(/\s+/g, " ");
}
```

- `value: string`: tipo do parâmetro;
- `: string` depois dos parênteses: retorno.

TypeScript pode inferir o retorno, mas explicitá-lo em funções públicas ajuda a
proteger o contrato.

## 10. Função que não retorna valor

```ts
function showMessage(message: string): void {
  console.log(message);
}
```

`void` indica que o valor de retorno não é usado como parte do contrato.

## 11. Função que nunca termina normalmente

```ts
function fail(message: string): never {
  throw new Error(message);
}
```

`never` representa um caminho que não produz valor porque lança ou não termina.

## 12. Parâmetros opcionais e padrão

```ts
function greet(name?: string): string {
  return `Olá, ${name ?? "estudante"}!`;
}
```

Com padrão:

```ts
function greet(name = "estudante"): string {
  return `Olá, ${name}!`;
}
```

## 13. Tipos em callbacks

```ts
const estimates = [1, 2, 3];

const doubled = estimates.map((estimate) => {
  return estimate * 2;
});
```

O tipo do callback é inferido a partir do array. Isso é tipagem contextual.

## 14. Erro estático e erro em execução

Erro estático:

```ts
const estimate: number = "três";
```

O analisador pode detectar sem executar.

Erro em execução:

```ts
const value = JSON.parse("{ inválido }");
```

Só aparece quando a operação ocorre.

Alguns problemas podem pertencer às duas categorias dependendo dos tipos e do
fluxo.

## 15. `any`

```ts
let value: any = "texto";
value.nonexistent().anything;
```

`any` desativa grande parte da verificação. Pode ser necessário em migrações
específicas, mas não deve ser usado para silenciar erros sem compreender a causa.

Trocar todos os erros por `any` remove justamente a proteção que motivou o
TypeScript.

## 16. `unknown`

```ts
let value: unknown = JSON.parse(text);
```

`unknown` aceita qualquer entrada, mas exige verificação antes do uso:

```ts
if (typeof value === "string") {
  console.log(value.toUpperCase());
}
```

Para dados externos, `unknown` comunica melhor que ainda não confiamos no formato.

## 17. Assertions

```ts
const input = document.querySelector("#title") as HTMLInputElement;
```

Uma assertion informa ao compilador que o desenvolvedor conhece um tipo mais
específico. Ela não verifica o DOM em execução.

Forma mais segura:

```ts
const input = document.querySelector("#title");

if (!(input instanceof HTMLInputElement)) {
  throw new Error("Campo title não encontrado.");
}
```

## 18. Tipos não alteram o valor

Isto não converte string em número:

```ts
const estimate = input.value as unknown as number;
```

O valor continua sendo string em execução. Converta:

```ts
const estimate = Number(input.value);
```

Depois valide:

```ts
if (!Number.isFinite(estimate)) {
  throw new Error("Estimativa inválida.");
}
```

## 19. Compilação

Em um projeto com TypeScript instalado:

```bash
npx tsc
```

O compilador:

1. lê os arquivos e configuração;
2. analisa tipos;
3. informa diagnósticos;
4. quando permitido, emite JavaScript.

O laboratório já contém a fonte `.ts` e a saída `.js` correspondente para não
depender de instalação externa nesta aula.

## 20. `tsconfig.json`

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "strict": true,
    "rootDir": "src",
    "outDir": "dist"
  },
  "include": ["src/**/*.ts"]
}
```

- `target`: versão aproximada do JavaScript gerado;
- `module`: formato de módulos;
- `strict`: conjunto de verificações rigorosas;
- `rootDir`: fontes;
- `outDir`: saída;
- `include`: arquivos do projeto.

Configuração será aprofundada na Aula 3.4.

## 21. `strict`

Ativar `strict` desde o início ajuda a evitar um projeto que parece tipado, mas
permite muitos valores indefinidos.

Migrações grandes podem exigir etapas. Projetos novos devem preferir configuração
estrita.

## 22. TypeScript não é validação de ambiente de execução

```ts
type Task = {
  title: string;
  estimate: number;
};

const response = await fetch("/api/task");
const data = (await response.json()) as Task;
```

`as Task` não verifica a resposta. Ele apenas altera a visão do compilador.

Valide:

```ts
function isTask(value: unknown): value is Task {
  if (typeof value !== "object" || value === null) {
    return false;
  }

  const candidate = value as Record<string, unknown>;

  return (
    typeof candidate.title === "string" &&
    typeof candidate.estimate === "number"
  );
}
```

Type guards serão aprofundados na Aula 3.3.

## 23. Laboratório guiado

Abra o [primeiro projeto TypeScript](../exemplos/aula-3.1/index.html).

### Etapa 1 — Compare os arquivos

Observe:

```text
src/app.ts
dist/app.js
```

Localize anotações que desapareceram na saída.

### Etapa 2 — Teste a entrada

O valor de um `<input>` chega como string. Informe:

- título válido;
- título com somente espaços;
- estimativa numérica;
- texto em um campo numérico, utilizando o DevTools se necessário.

### Etapa 3 — Observe os contratos

O painel apresenta:

- valor recebido;
- tipo em ambiente de execução com `typeof`;
- valor convertido;
- objeto final validado.

### Etapa 4 — Leia os erros esperados

O arquivo `src/type-errors.ts` contém exemplos deliberadamente inválidos. Ele serve
para leitura e não faz parte da saída executável.

## 24. Erros comuns

### Anotar tudo

Tipagem redundante aumenta ruído. Aproveite inferência quando o tipo é evidente.

### Usar `any` para terminar rápido

O código compila, mas perde proteção.

### Acreditar que `as` converte valores

Assertions não alteram ambiente de execução.

### Confiar em JSON porque existe um tipo

Dados externos continuam desconhecidos até validação.

### Esperar que o navegador execute `.ts`

O navegador recebe JavaScript gerado.

### Corrigir todos os erros com `!`

O operador de non-null assertion silencia a possibilidade de ausência sem criar
verificação real.

## 25. Boas práticas

- mantenha conhecimento sólido de JavaScript;
- use inferência para valores locais simples;
- explicite contratos públicos;
- prefira `unknown` para entrada externa;
- evite `any`;
- converta valores em ambiente de execução;
- valide dados externos;
- habilite `strict`;
- separe `src` e `dist`;
- não edite manualmente a saída gerada em projetos reais.

## 26. Exercícios

### Exercício 1 — Primitivas

Tipar nome, carga horária e estado de conclusão.

### Exercício 2 — Função

Criar `calculateProgress(completed, total): number`.

### Exercício 3 — Array

Criar um array de títulos e impedir inserção de número.

### Exercício 4 — Entrada externa

Receber `unknown` e confirmar se é string.

### Exercício 5 — DOM

Consultar um input e validar com `instanceof`.

## 27. Desafio

Migre uma regra do Módulo 2:

- defina tipos de parâmetros;
- defina retorno;
- remova `any`;
- crie um exemplo que deve falhar na análise;
- mantenha validação de ambiente de execução;
- compare o `.ts` e o `.js`.

## 28. Lista de verificação de conclusão

- [ ] Sei diferenciar TypeScript, JavaScript e framework.
- [ ] Entendo que o navegador executa JavaScript.
- [ ] Sei explicar apagamento de tipos.
- [ ] Uso inferência e anotações conscientemente.
- [ ] Consigo tipar arrays, objetos e funções.
- [ ] Sei por que evitar `any`.
- [ ] Entendo o papel de `unknown`.
- [ ] Não uso assertion como validação.
- [ ] Sei ler um `tsconfig.json`.
- [ ] Valido entrada externa em ambiente de execução.

## 29. Critérios de avaliação

| Critério | Pontos |
|---|---:|
| Tipos e inferência corretos | 25 |
| Funções tipadas | 20 |
| Conversão e validação em ambiente de execução | 25 |
| Ausência de `any` desnecessário | 15 |
| Explicação da saída JavaScript | 15 |
| **Total** | **100** |

## Resumo

Nesta aula, aprendemos que:

- TypeScript adiciona análise estática ao JavaScript;
- o navegador executa o JavaScript gerado;
- os tipos são apagados;
- inferência evita anotações redundantes;
- `any` desativa proteção e `unknown` exige verificação;
- assertions não convertem nem validam valores;
- entrada externa precisa de validação em ambiente de execução.

## Próxima aula

Na Aula 3.2, criaremos contratos reutilizáveis com interfaces, type aliases,
propriedades opcionais, readonly e composição de tipos.
