Da trilha de TypeScript Este conceito ainda não saiu como card do dia. ir para o card de hoje

TypeScript Tipos Intermediário

Utility types

Utility types são tipos genéricos fornecidos pelo TypeScript que transformam outros tipos. Eles evitam repetição e mantêm a consistência quando a forma de um tipo base muda. Os mais usados são Partial<T>, Required<T>, Pick<T, K>, Omit<T, K>, Record<K, V>, ReturnType<F> e Parameters<F>.

Partial<T> torna todas as propriedades de T opcionais, enquanto Required<T> faz o contrário: todas se tornam obrigatórias. Pick<T, K> cria um tipo com apenas as chaves K de T, e Omit<T, K> cria um tipo sem essas chaves. Record<K, V> constrói um objeto com chaves do tipo K e valores do tipo V.

Já ReturnType<F> extrai o tipo de retorno de uma função F, e Parameters<F> extrai a tupla de parâmetros. Esses dois são úteis para reutilizar a assinatura de funções existentes sem duplicar código.

Neste card, você vai praticar a combinação desses utility types para modelar dados de forma segura e expressiva.

Pontos-chave

  • Partial<T> deixa todas as propriedades opcionais; Required<T> as torna obrigatórias.
  • Pick<T, K> seleciona chaves; Omit<T, K> remove chaves.
  • Record<K, V> cria um mapa com chaves K e valores V.
  • ReturnType<F> e Parameters<F> extraem tipos de funções existentes.
  • Utility types são composáveis: você pode aninhar um dentro do outro.
utility_types.ts
// Exemplo prático de utility types em TypeScript
interface Usuario {
  id: number;
  nome: string;
  email: string;
  ativo: boolean;
}

// Partial: atualização parcial de usuário
function atualizarUsuario(id: number, dados: Partial<Usuario>): Usuario {
  const base: Usuario = { id, nome: "Anônimo", email: "", ativo: false };
  return { ...base, ...dados };
}

// Required: garante que todos os campos estejam presentes
function validarUsuario(u: Required<Usuario>): void {
  console.log(`Usuário ${u.nome} validado.`);
}

// Pick e Omit
type ResumoUsuario = Pick<Usuario, "id" | "nome">;
type UsuarioSemEmail = Omit<Usuario, "email">;

// Record: mapa de id para usuário
const usuariosPorId: Record<number, ResumoUsuario> = {
  1: { id: 1, nome: "Ana" },
  2: { id: 2, nome: "Bruno" },
};

// ReturnType e Parameters
function criarUsuario(nome: string, email: string): Usuario {
  return { id: Date.now(), nome, email, ativo: true };
}
type RetornoCriar = ReturnType<typeof criarUsuario>;
type ParamsCriar = Parameters<typeof criarUsuario>;

const params: ParamsCriar = ["Carla", "carla@ex.com"];
const novo: RetornoCriar = criarUsuario(...params);

console.log(atualizarUsuario(1, { nome: "Ana Silva" }));
validarUsuario({ id: 3, nome: "Dora", email: "dora@ex.com", ativo: true });
console.log(usuariosPorId[2].nome);
console.log(novo.nome);

Exercícios

  1. 1
    Fácil

    Atualização parcial com Partial

    Crie uma função atualizarProduto que recebe um id e um objeto do tipo Partial<Produto> e retorna um Produto completo, usando valores padrão para os campos não informados. O tipo Produto tem id: number, nome: string e preco: number.

    Resolver
  2. 2
    Médio

    Seleção e omissão de campos

    Dado o tipo Funcionario com id, nome, cargo e salario, crie dois tipos: ResumoFuncionario que contém apenas id e nome, e FuncionarioSemSalario que contém todos os campos exceto salario. Depois, escreva uma função imprimirResumo que recebe um ResumoFuncionario e imprime "ID: X, Nome: Y".

    Resolver
  3. 3
    Desafio

    Mapa com Record e inferência de função

    Crie uma função criarMapa que recebe um array de objetos com id: number e nome: string e retorna um Record<number, string> mapeando id para nome. Além disso, use ReturnType e Parameters para tipar uma função executar que chama criarMapa com os parâmetros corretos e retorna o mesmo tipo. Imprima o mapa resultante.

    Resolver

Continue estudando