Pular para o conteúdo
TypeScript

Parâmetros Opcionais no TypeScript 2026

Parâmetros opcionais com ? tornam suas funções flexíveis sem sacrificar tipagem. Aprenda quando usar ?, quando usar valores default, como tratar undefined e quando function overloads fazem mais

Por que isso é importante

Parâmetros opcionais com ? tornam suas funções flexíveis sem sacrificar tipagem. Aprenda quando usar ?, quando usar valores default, como tratar undefined e quando function overloads fazem mais sentido.

Parâmetros opcionais: como funcionam

No TypeScript, o ? depois do nome do parâmetro diz: esse argumento pode ou não ser passado. Quando não é passado, o valor fica undefined. O tipo real da variável vira T | undefined, e o compilador te obriga a tratar esse caso antes de usar o valor.

Tem uma regra que muita gente esquece: parâmetros opcionais precisam vir depois dos obrigatórios. Você não pode ter (nome?: string, idade: number) -- o TypeScript não aceita. Faz sentido: como o compilador saberia se você passou o primeiro ou o segundo?

A alternativa mais usada ao ? é o valor default. Quando você define nome: string = "Anônimo", o parâmetro se torna opcional automaticamente -- sem precisar do ?. A diferença? Com default, o valor nunca é undefined dentro da função. Com ?, você precisa checar.

// Com ? - precisa checar undefined
function saudar(nome: string, saudacao?: string): string {
  if (saudacao) {
    return `${saudacao}, ${nome}!`;
  }
  return `Olá, ${nome}!`;
}

saudar("Maria");           // "Olá, Maria!"
saudar("Maria", "Oi");    // "Oi, Maria!"

// Com default - sem undefined pra tratar
function saudarDefault(nome: string, saudacao: string = "Olá"): string {
  return `${saudacao}, ${nome}!`;
}

saudarDefault("João");         // "Olá, João!"
saudarDefault("João", "Eai"); // "Eai, João!"

Passo a passo: dominando parâmetros opcionais

  1. Adicione ? depois do nome do parâmetro — Isso marca como opcional. O tipo real vira T | undefined. Sempre coloque os opcionais no final da lista de parâmetros.
  2. Trate o undefined antes de usar o valor — Use if, operador ?? (nullish coalescing) ou ! (non-null assertion, com cuidado). O compilador vai reclamar se você ignorar.
  3. Prefira default values quando faz sentido — Se existe um valor padrão claro, use param: tipo = valorDefault. Evita checks de undefined e torna a API da função mais previsível.
  4. Use objetos de configuração para muitos opcionais — Quando a função tem 3+ parâmetros opcionais, agrupe num objeto: function criar(config: { nome: string; cor?: string; tamanho?: number }).
  5. Considere function overloads para APIs complexas — Quando o tipo de retorno muda conforme os parâmetros passados, overloads dão tipagem precisa em cada cenário.

Exemplos práticos do dia a dia

Operador ?? para valores fallback

O operador nullish coalescing (??) é perfeito pra parâmetros opcionais. Ele só usa o fallback quando o valor é null ou undefined -- diferente do ||, que também pega string vazia e zero.

function criarUsuario(
  nome: string,
  email?: string,
  idade?: number
) {
  return {
    nome,
    email: email ?? "nao-informado@email.com",
    idade: idade ?? 0,
  };
}

criarUsuario("Ana");
// { nome: "Ana", email: "nao-informado@email.com", idade: 0 }

criarUsuario("Ana", "ana@dev.com", 28);
// { nome: "Ana", email: "ana@dev.com", idade: 28 }

Objeto de configuração com opcionais

Quando tem vários parâmetros opcionais, fica muito mais limpo usar um objeto. Dá pra desestruturar direto no parâmetro e aplicar defaults.

interface ConfigBotao {
  texto: string;
  cor?: string;
  tamanho?: "sm" | "md" | "lg";
  desabilitado?: boolean;
}

function criarBotao({
  texto,
  cor = "blue",
  tamanho = "md",
  desabilitado = false,
}: ConfigBotao) {
  return { texto, cor, tamanho, desabilitado };
}

criarBotao({ texto: "Salvar" });
// { texto: "Salvar", cor: "blue", tamanho: "md", desabilitado: false }

criarBotao({ texto: "Deletar", cor: "red", tamanho: "lg" });
// { texto: "Deletar", cor: "red", tamanho: "lg", desabilitado: false }

Function Overloads

Overloads servem quando o tipo de retorno depende de quais parâmetros foram passados. Você declara as assinaturas possíveis e depois a implementação genérica.

// Overload 1: sem formato, retorna Date
function parsearData(input: string): Date;
// Overload 2: com formato, retorna string
function parsearData(input: string, formato: string): string;
// Implementação
function parsearData(input: string, formato?: string): Date | string {
  const data = new Date(input);
  if (formato) {
    return data.toLocaleDateString("pt-BR");
  }
  return data;
}

const d1 = parsearData("2025-07-10");       // tipo: Date
const d2 = parsearData("2025-07-10", "BR"); // tipo: string

Erros comuns com parâmetros opcionais

Armadilhas que derrubam projetos

Colocar opcional antes de obrigatório: o TypeScript não compila. Opcionais sempre no final.

Usar || ao invés de ?? para fallback: o || trata 0, '' e false como falsy. Se idade é 0, || substitui por default. O ?? só age com null/undefined.

Ignorar o undefined: marcar com ? e usar direto sem check gera o 'Cannot read properties of undefined' em runtime.

Misturar ? com default: não faz sentido usar os dois. Se tem default, o parâmetro já é opcional. Escolha um.

Excesso de parâmetros opcionais: mais de 3 opcionais numa função é sinal de que precisa de um objeto de configuração.

Checklist: Parâmetros opcionais corretos

Checklist de Parâmetros Opcionais

  • Parâmetros opcionais estão depois dos obrigatórios
  • Todo valor opcional é tratado antes de uso (if, ??, default)
  • Usei ?? ao invés de || para nullish coalescing
  • Funções com 3+ opcionais usam objeto de configuração
  • Overloads aplicados quando retorno muda conforme parâmetros
  • Não misturei ? com valor default no mesmo parâmetro
  • Propriedades opcionais em interfaces usam ? corretamente
  • Testes cobrem cenários com e sem os parâmetros opcionais

Leve seu TypeScript pro próximo nível

Parâmetros opcionais são a ponta do iceberg. No CrazyStack, você constrói APIs reais, tipando cada camada do projeto -- do banco ao front. Aprenda TypeScript do jeito que o mercado pede: com código de produção, não com exemplos genéricos.