Introdução ao TypeScript - Desenvolvimento JavaScript com Type Safety

iniciante | 50 min leitura | 2024.12.16

O que Você Aprenderá Neste Tutorial

✓ Tipos básicos do TypeScript
✓ Como funciona a inferência de tipos
✓ Interfaces e type aliases
✓ Union types e literal types
✓ Fundamentos de generics
✓ Padrões práticos de definição de tipos

Pré-requisitos

  • Conhecimento básico de JavaScript
  • Node.js instalado

Configuração do Projeto

# Criar diretório do projeto
mkdir typescript-tutorial
cd typescript-tutorial

# Criar package.json
npm init -y

# Instalar TypeScript
npm install -D typescript ts-node @types/node

# Criar tsconfig.json
npx tsc --init

Configuração do tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"]
}

Passo 1: Tipos Básicos

Tipos Primitivos

// src/01-primitives.ts

// String
let nome: string = "João";
let saudacao: string = `Olá, ${nome}`;

// Number
let idade: number = 25;
let preco: number = 1980.5;
let hex: number = 0xff;

// Boolean
let estaAtivo: boolean = true;
let temPermissao: boolean = false;

// null e undefined
let nada: null = null;
let naoDefinido: undefined = undefined;

// any (desativa verificação de tipos - evite quando possível)
let qualquerCoisa: any = "string";
qualquerCoisa = 123;
qualquerCoisa = true;

// unknown (mais seguro que any)
let valorDesconhecido: unknown = "olá";
// valorDesconhecido.toUpperCase(); // Erro
if (typeof valorDesconhecido === "string") {
  valorDesconhecido.toUpperCase(); // OK
}

Arrays e Tuplas

// src/02-arrays.ts

// Arrays
let numeros: number[] = [1, 2, 3, 4, 5];
let nomes: string[] = ["Alice", "Bob", "Charlie"];

// Notação genérica
let valores: Array<number> = [10, 20, 30];

// Tuplas (arrays de tamanho e tipo fixos)
let tupla: [string, number] = ["idade", 25];
let rgb: [number, number, number] = [255, 128, 0];

// Tuplas rotuladas
let usuario: [nome: string, idade: number] = ["João", 30];

// Arrays readonly
let numerosReadonly: readonly number[] = [1, 2, 3];
// numerosReadonly.push(4); // Erro

Passo 2: Tipos de Função

Tipos Básicos de Função

// src/04-functions.ts

// Tipos de parâmetros e retorno
function somar(a: number, b: number): number {
  return a + b;
}

// Arrow functions
const multiplicar = (a: number, b: number): number => a * b;

// Parâmetros opcionais
function cumprimentar(nome: string, saudacao?: string): string {
  return `${saudacao || "Olá"}, ${nome}!`;
}

// Rest parameters
function soma(...numeros: number[]): number {
  return numeros.reduce((acc, curr) => acc + curr, 0);
}

console.log(soma(1, 2, 3, 4, 5)); // 15

Passo 3: Type Aliases e Interfaces

Type Aliases (type)

// Type aliases básicos
type ID = string | number;
type Ponto = { x: number; y: number };

// Union types
type Status = "pendente" | "aprovado" | "rejeitado";

let usuarioId: ID = "user_123";
let pedidoId: ID = 456;
let statusAtual: Status = "pendente";

// Intersection types
type Nomeado = { nome: string };
type ComIdade = { idade: number };
type Pessoa = Nomeado & ComIdade;

const pessoa: Pessoa = {
  nome: "João",
  idade: 30
};

Interfaces

// Interface básica
interface Usuario {
  id: number;
  nome: string;
  email: string;
  idade?: number; // Opcional
  readonly criadoEm: Date; // Readonly
}

const usuario: Usuario = {
  id: 1,
  nome: "Alice",
  email: "alice@exemplo.com",
  criadoEm: new Date()
};

// Herança de interface
interface Funcionario extends Usuario {
  departamento: string;
  salario: number;
}

Passo 4: Generics

Generics Básicos

// Função genérica
function identidade<T>(valor: T): T {
  return valor;
}

const str = identidade<string>("olá");
const num = identidade(42); // Inferência de tipo: number

// Função genérica com arrays
function primeiro<T>(arr: T[]): T | undefined {
  return arr[0];
}

const primeiroNumero = primeiro([1, 2, 3]); // number | undefined

Interfaces Genéricas

// Tipo de resposta da API
interface RespostaApi<T> {
  dados: T;
  status: number;
  mensagem: string;
}

interface Usuario {
  id: number;
  nome: string;
}

const respostaUsuario: RespostaApi<Usuario> = {
  dados: { id: 1, nome: "Alice" },
  status: 200,
  mensagem: "Sucesso"
};

Passo 5: Utility Types

Utility Types Incorporados

interface Usuario {
  id: number;
  nome: string;
  email: string;
  idade: number;
}

// Partial - torna tudo opcional
type UsuarioParcial = Partial<Usuario>;
const dadosAtualizacao: UsuarioParcial = { nome: "Novo Nome" };

// Pick - seleciona propriedades específicas
type UsuarioBasico = Pick<Usuario, "id" | "nome">;

// Omit - exclui propriedades específicas
type UsuarioSemEmail = Omit<Usuario, "email">;

// Readonly - torna tudo readonly
type UsuarioReadonly = Readonly<Usuario>;

Resumo

Ao aproveitar o sistema de tipos do TypeScript, você pode detectar erros em tempo de compilação e escrever código mais seguro. Comece com tipos básicos e avance até dominar generics e utility types.

← Voltar para a lista