Tipos de Utilidade do TypeScript — Os Que Valem a Pena Memorizar (e os Demais)
Parcial, Escolha, Omita, Gravação, TipoDeRetorno, Parâmetros, Aguardado — oito tipos úteis com exemplos antes e depois e uma avaliação honesta sobre quais você usará todas as semanas.
Você provavelmente já leu uma página de documentação do TypeScript que lista mais de 20 tipos úteis em ordem alfabética, definindo cada um em uma frase, e ficou em dúvida sobre quais deles é melhor internalizar e quais existem apenas para pessoas que escrevem código interno de framework. Esta é a versão mais honesta: oito tipos, exemplos concretos antes e depois, e uma resposta direta sobre o uso diário versus o uso ocasional.
Se você estiver começando a partir de JSON bruto e ainda não tiver escrito suas interfaces, o convertedor de JSON para TypeScript vai te levar a uma interface básica em segundos — então volte aqui para aplicar esses tipos úteis sobre ela.
Partial — Uso semanal. Aprenda primeiro.
Torna todas as propriedades de T opcionais. O caso canônico é atualizações no estilo PATCH, onde você envia apenas os campos que mudaram.
// Before: manually duplicating the interface with optional versions of everything
interface UserUpdate {
name?: string;
email?: string;
age?: number;
}
// After: Partial derives it from the source of truth
interface User {
name: string;
email: string;
age: number;
}
function updateUser(id: string, updates: Partial<User>) {
// updates.name is string | undefined — TypeScript knows
}
O problema com a versão "antes": se você adicionar um campo a User, você precisa lembrar de adicionar também a UserUpdate . Com Partial<User>, adicionar um campo à interface de origem torna esse campo disponível nas atualizações automaticamente. Os tipos permanecem sincronizados.
Required — Uso mensal, mas economiza em uma situação específica.
O inverso de Partial — remove todas as ? de um tipo. Mais útil após validação: você recebe um objeto de configuração com tipagem fraca, valida que todos os campos estão presentes e então deseja que o TypeScript pare de sugerir que tudo pode ser indefinido.
// Before: after validating, you still fight undefined checks everywhere
interface Config {
apiUrl?: string;
timeout?: number;
retries?: number;
}
function initApp(config: Config) {
config.apiUrl?.trim(); // need optional chaining even after checking
}
// After: Required signals "this has been validated, stop warning me"
function validateAndInit(raw: Config): void {
if (!raw.apiUrl) throw new Error("apiUrl required");
if (!raw.timeout) throw new Error("timeout required");
if (!raw.retries) throw new Error("retries required");
const config = raw as Required<Config>;
config.apiUrl.trim(); // no optional chaining needed
}
Observação honesta: Required<T> não faz validação em tempo de execução — você ainda precisa escrever as verificações. Ele apenas muda o que o TypeScript acredita no nível de tipo. Use para comunicar "isso já foi validado" no nível de tipo.
Pick — Uso semanal. Especifique o que você quer.
Cria um novo tipo contendo apenas as propriedades que você nomeia de T. Útil quando você quer um subconjunto de uma interface maior — formas de API pública, modelos de visualização, respostas serializadas.
// Before: manually maintaining a separate interface that drifts from User
interface UserPublicProfile {
name: string;
bio: string;
avatarUrl: string;
}
// After: Pick stays in sync with the source
interface User {
id: string;
name: string;
email: string; // private — shouldn't go to clients
passwordHash: string; // definitely private
bio: string;
avatarUrl: string;
}
type UserPublicProfile = Pick<User, "name" | "bio" | "avatarUrl">;
Pick é a ferramenta certa quando a lista de propriedades que você deseja é mais curta do que a lista que você precisaria exclude. Quando isso acontece no sentido oposto, use Omit.
Omit — Uso semanal. Especifique o que você não quer.
Complemento de Pick — cria um tipo com todas as propriedades de T exceto as que você nomeia. Quando você tem uma interface grande e apenas alguns campos para excluir, Omit torna a intenção mais clara do que listar todos os campos que você deseja.
// Before: manually listing every field except the sensitive ones
// Easy to miss a new field added to User later
interface UserForClient {
id: string;
name: string;
email: string;
bio: string;
avatarUrl: string;
// passwordHash intentionally omitted — but a future dev might not know that
}
// After: Omit states the exclusion explicitly
type UserForClient = Omit<User, "passwordHash">;
// If User gains a new "address" field, UserForClient gets it automatically
Uma coisa que nem Pick nem Omit faz: mudar o tipo de propriedades individuais. Se você quiser selecionar campos e e transformar seus tipos, você está olhando para um tipo mapeado, que é uma ferramenta completamente diferente.
Record — Uso semanal. O dicionário tipado.
Cria um tipo de objeto onde todas as chaves são do tipo K e todos os valores são do tipo V. O verdadeiro ganho surge quando K é um tipo de união — o TypeScript dará erro se você estiver faltando uma chave. As assinaturas de índice genéricas aceitam objetos incompletos silenciosamente; Record com uma chave de união não faz isso.
// Before: index signature with no exhaustiveness checking
const rolePermissions: { [key: string]: string[] } = {
admin: ["read", "write", "delete"],
editor: ["read", "write"],
// forgot "viewer" — TypeScript doesn't notice
};
// After: Record with a union key enforces completeness
type Role = "admin" | "editor" | "viewer";
const rolePermissions: Record<Role, string[]> = {
admin: ["read", "write", "delete"],
editor: ["read", "write"],
viewer: ["read"],
// TypeScript error if any Role is missing
// TypeScript error if you try to add an unknown key
};
A verificação de exaustividade é o verdadeiro ganho. Importa quando as chaves representam algo significativo, como papéis, tipos de eventos, métodos HTTP ou códigos de status — qualquer coisa onde a ausência de um caso é um erro, e não apenas uma omissão.
ReturnType — Uso semanal se você consumir funções de terceiros.
Extraí o tipo de retorno de uma função. Mais útil quando você está consumindo uma função de uma biblioteca e deseja tipar uma variável que contém seu resultado — sem precisar importar o tipo de retorno separadamente (o que bibliotecas nem sempre exportam de forma limpa).
// Before: manually annotating the return type — it can drift
function getCurrentUser() {
return { id: "u1", name: "Alice", roles: ["admin"] as const };
}
let cachedUser: { id: string; name: string; roles: readonly string[] };
// If getCurrentUser's return changes, this annotation doesn't update automatically
// After: ReturnType derives it and keeps in sync
type CurrentUser = ReturnType<typeof getCurrentUser>;
let cachedUser: CurrentUser;
// Especially useful with unexported library types:
import { useQuery } from "@tanstack/react-query";
type QueryResult = ReturnType<typeof useQuery>;
// No need to figure out what QueryObserverResult<...> looks like or import it
Parameters — Uso ocasional. Principalmente para envoltórios.
Extraí os tipos de parâmetros de uma função como uma tupla. Visão honesta: você não usará essa ferramenta semanal a menos que escreva muitas funções de envoltório ou utilidades de ordem superior. Mas quando precisar, não há alternativa limpa.
// Before: manually duplicating parameter types in the wrapper
function createEvent(
type: string,
payload: Record<string, unknown>,
timestamp: number
) { /* ... */ }
// Every time createEvent changes, this wrapper needs a manual update:
function loggedCreateEvent(
type: string,
payload: Record<string, unknown>,
timestamp: number
) {
console.log("Creating event:", type);
return createEvent(type, payload, timestamp);
}
// After: Parameters keeps the wrapper in sync automatically
function loggedCreateEvent(...args: Parameters<typeof createEvent>) {
console.log("Creating event:", args[0]);
return createEvent(...args);
}
O padrão de espalhamento + rest (...args: Parameters<F>) é a principal convenção. Também aparece em mocks de testes: jest.fn<ReturnType<F>, Parameters<F>>() dá a você um mock totalmente tipado sem precisar importar a assinatura da função separadamente.
Awaited — Use quando precisar desempacotar tipos de Promise sem chamá-los.
Adicionado no TypeScript 4.5 (lançado em novembro de 2021). Desempacota recursivamente Promise<T> para obter T. Antes de existir, obter o tipo resolvido de uma função assíncrona significava escrever um tipo condicional: ReturnType<F> extends Promise<infer U> ? U : never — que quebra em Promises duplamente envolvidas e é difícil de ler em diferenças.
// Before: conditional type to unwrap — breaks on nested Promises
async function fetchUser(id: string) {
const res = await fetch(`/api/users/${id}`);
return res.json() as { id: string; name: string; email: string };
}
type FetchedUser =
ReturnType<typeof fetchUser> extends Promise<infer U> ? U : never;
// Works for Promise<T> but not Promise<Promise<T>>
// After: Awaited handles both cases cleanly
type FetchedUser = Awaited<ReturnType<typeof fetchUser>>;
// Awaited recursively unwraps:
type A = Awaited<Promise<string>>; // string
type B = Awaited<Promise<Promise<string>>>; // string
type C = Awaited<string>; // string (no-op on non-Promise)
A combinação Awaited<ReturnType<typeof fn>> vale a pena memorizar como uma unidade — cobre 90% de extração de tipos assíncronos no código de aplicação.
Cheatsheet
| Tipo útil | O que faz | Frequência de uso | Caso de uso principal |
|---|---|---|---|
Partial<T> | Todas as propriedades tornam-se opcionais | Semanalmente | Corpos de atualização PATCH |
Required<T> | Todas as propriedades opcionais tornam-se obrigatórias | Por mês | Sinal de "completo" após validação |
Pick<T, K> | Mantém apenas as propriedades nomeadas | Semanalmente | Formas de API pública, modelos de visualização |
Omit<T, K> | Remove as propriedades nomeadas | Semanalmente | Remoção de campos sensíveis ou irrelevante |
Record<K, V> | Objeto com chaves do tipo K e valores do tipo V | Semanalmente | Dicionários tipados com verificação de exaustividade |
ReturnType<F> | Extraí o tipo de retorno de uma função | Semanal (especialmente com bibliotecas) | Tipar uma variável a partir de um tipo inferido ou não exportado |
Parameters<F> | Extraí os tipos de parâmetros de uma função como uma tupla | Ocasional | Funções de envoltório, mocks tipados |
Awaited<T> | Desempacota recursivamente tipos de Promise | Ocasional | Obter o tipo resolvido de funções assíncronas |
Os que não estão nesta lista
O TypeScript também inclui Readonly<T>, NonNullable<T>, Extract<T,U>, Exclude<T,U>, InstanceType<C>, ConstructorParameters<C>e várias tipos literais de modelo. Eles são reais e ocasionalmente úteis, mas surgem em códigos de bibliotecas, utilidades genéricas e programação de nível de tipo — não em lógica típica de aplicação. Se você memorizou os oito acima, procure os demais quando realmente os precisar.
O princípio subjacente é o mesmo em todos eles: descrever uma transformação de um tipo existente em vez de duplicá-lo. Os nomes específicos dos tipos úteis são apenas vocabulário para expressar essa intenção ao TypeScript.
Você também pode gostar
Instale nossas extensões
Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida
恵 O placar chegou!
Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!
Ferramentas essenciais
Ver tudo Novas chegadas
Ver tudoAtualizar: Nosso ferramenta mais recente was added on Jun 26, 2026
