TypeScript não é complicado. O problema é que a galera tenta ensinar tudo de uma vez: generics, decorators, utility types, type guards… aí você se perde e volta pro JavaScript. A real é que você não precisa saber tudo isso pra começar. Você precisa de uns 20% do TypeScript que resolve 80% dos seus problemas. Eu uso TypeScript no dia a dia e, bem, a maior parte do tempo eu uso só o básico. E funciona.

Então vou te mostrar exatamente isso: o mínimo que você precisa saber pra começar a usar TypeScript hoje e sentir os benefícios sem se perder na documentação.

O que é TypeScript

É JavaScript com bomba. Você escreve, o TypeScript verifica se tá tudo certo, compila pra JavaScript normal. Fim. É uma linguagem nova que no fim, se torna JavaScript.

TypeScript
// JavaScript
function sum(a, b) {
  return a + b;
}

// TypeScript
function sum(a: number, b: number): number {
  return a + b;
}

A diferença? Se você tentar fazer sum("10", 20), o TypeScript avisa antes de rodar. No JavaScript você só descobre quando quebra em produção.

Tipos básicos

1. string, number, boolean

TypeScript
const name: string = "Gabriel";
const age: number = 25;
const isActive: boolean = true;

Simples. Mas na real, você raramente precisa escrever isso explicitamente porque o TypeScript infere automaticamente:

TypeScript
const name = "Gabriel"; // TypeScript já sabe que é string
const age = 25; // TypeScript já sabe que é number

Então você só declara o tipo quando:

  • É um parâmetro de função
  • É uma propriedade de objeto/classe
  • O TypeScript não consegue inferir sozinho

2. Arrays

TypeScript
const numbers: number[] = [1, 2, 3];
const names: string[] = ["João", "Maria"];

// Ou usando a sintaxe alternativa (menos comum)
const moreNumbers: Array<number> = [1, 2, 3];

Se você tentar fazer numbers.push("texto"), o TypeScript reclama. Simples assim.

3. Objects (interfaces)

TypeScript
interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

const user: User = {
  id: 1,
  name: "Gabriel",
  email: "gabriel@example.com",
  isActive: true
};

Interface é basicamente a “forma” do seu objeto. Se você esquecer um campo ou colocar o tipo errado, o TypeScript avisa. É muito parecida com o que já temos em outras linguagens tipadas, como o Java.

4. Optional (?)

TypeScript
interface User {
  id: number;
  name: string;
  email: string;
  phone?: string; // opcional
}

// Isso funciona
const user1: User = {
  id: 1,
  name: "Gabriel",
  email: "gabriel@example.com"
};

// Isso também funciona
const user2: User = {
  id: 2,
  name: "João",
  email: "joao@example.com",
  phone: "11999999999"
};

O ? significa que o campo é opcional.

5. any (quando você desiste)

TypeScript
let anything: any = "texto";
anything = 123;
anything = true;
anything = { name: "teste" };

any aceita qualquer coisa. É basicamente voltar pro JavaScript. Use só quando você realmente não sabe o tipo ou quando tá lidando com código legado. Mas evita, só evita. Se você usa any não estará aproveitando as funcionalidades do TypeScript.

6. unknown (any mais seguro)

TypeScript
let value: unknown = "texto";

// Isso dá erro
// let text: string = value;

// Você precisa verificar antes
if (typeof value === "string") {
  let text: string = value; // Agora funciona
}

unknown é como um any que te força a verificar o tipo antes de usar. É mais seguro.

Funções

Tipando parâmetros e retorno

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

function greet(name: string): string {
  return `Hello, ${name}`;
}

function log(message: string): void {
  console.log(message);
  // void = não retorna nada
}

Parâmetros opcionais

TypeScript
function greet(name: string, greeting?: string): string {
  if (greeting) {
    return `${greeting}, ${name}`;
  }
  return `Hello, ${name}`;
}

greet("Gabriel"); // "Hello, Gabriel"
greet("Gabriel", "Hi"); // "Hi, Gabriel"

Valores padrão

TypeScript
function greet(name: string, greeting: string = "Hello"): string {
  return `${greeting}, ${name}`;
}

Quando você coloca um valor padrão, o tipo já é inferido automaticamente.

Union Types do TypeScript

TypeScript
function format(value: string | number): string {
  return value.toString();
}

format("texto"); // funciona
format(123); // funciona
format(true); // erro!

O | significa “ou”. A variável pode ser string ou number. Isso não é algo comum em linguagens tipadas. Aliás, útil pra quando você recebe dados de API que podem vir em formatos diferentes:

TypeScript
interface Response {
  data: string | null;
  error: string | null;
}

Type vs Interface

Tem gente que passa horas discutindo qual usar. A real? Tanto faz. Pra 99% dos casos, são a mesma coisa.

TypeScript
// Interface
interface User {
  name: string;
  email: string;
}

// Type
type User = {
  name: string;
  email: string;
};

Quando usar cada um:

  • Interface: pra objetos, classes
  • Type: pra union types, tipos mais complexos

Mas sério, se você usar sempre interface ou sempre type, tá tudo bem.

Exemplo prático: API com TypeScript

TypeScript
interface Product {
  id: number;
  name: string;
  price: number;
  inStock: boolean;
}

async function getProduct(id: number): Promise<Product | null> {
  try {
    const response = await fetch(`/api/products/${id}`);
    const data: Product = await response.json();
    return data;
  } catch (error) {
    console.error(error);
    return null;
  }
}

async function updateProduct(id: number, updates: Partial<Product>): Promise<boolean> {
  try {
    const response = await fetch(`/api/products/${id}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(updates)
    });
    return response.ok;
  } catch (error) {
    console.error(error);
    return false;
  }
}

Olha como fica mais claro:

  • Você sabe que getProduct recebe um number e retorna uma Promise de Product ou null
  • Partial<Product> significa que você pode passar só alguns campos do Product
  • Se você tentar passar uma string pra getProduct, o TypeScript avisa antes

Dicas práticas

1. Deixe o TypeScript inferir quando possível

TypeScript
// Ruim (verboso demais)
const numbers: number[] = [1, 2, 3];

// Bom (mais limpo)
const numbers = [1, 2, 3];

2. Use interfaces pra modelar seus dados

Sempre que você tiver dados vindo de API, crie uma interface. Ajuda demais na hora de usar.

TypeScript
interface UserResponse {
  id: number;
  name: string;
  email: string;
  createdAt: string;
}

3. Evite any

Se você tá usando any demais, você tá perdendo o benefício do TypeScript. Se não souber o tipo, use unknown e faça as verificações necessárias.

4. Configure o tsconfig.json

JSON
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

"strict": true é o mais importante. Ativa todas as verificações estritas.

O que você NÃO precisa saber (ainda)

Tem um monte de coisa avançada que você pode ignorar no começo:

  • Generics (até você precisar criar uma função genérica)
  • Decorators (até você usar Angular ou NestJS)
  • Utility Types complexos (até você precisar)
  • Type Guards avançados
  • Conditional Types

Você vai aprendendo conforme precisa. Não tenta aprender tudo de uma vez.

No fim das contas

TypeScript não é sobre saber todas as features. É sobre ter autocomplete melhor, pegar erros antes de rodar, e ter código mais fácil de manter. Você começa usando só tipos básicos, interfaces, e já sente a diferença. O resto você vai aprendendo com o tempo, conforme o código vai exigindo.

E o melhor: você pode adotar TypeScript aos poucos. Começa com um arquivo, vai migrando devagar. Não precisa refazer o projeto inteiro de uma vez. Se você usa JavaScript e vive tomando erro de undefined is not a function ou cannot read property of undefined, TypeScript resolve. Simples assim.