Por Que Utility Types Importam
Utility Types são transformações de tipo embutidas no TypeScript. Eles permitem criar novos tipos a partir de tipos existentes sem duplicar código. Menos código, mais expressividade, menos erros.
1. Partial<T>: Todos os campos opcionais
Perfeito para formulários de atualização onde nem todos os campos precisam ser enviados:
interface User {
name: string;
email: string;
age: number;
}
// Todos os campos viram opcionais
type UpdateUserDTO = Partial<User>;
// { name?: string; email?: string; age?: number; }
async function updateUser(id: string, data: Partial<User>) {
// Pode receber apenas { email: "novo@email.com" }
}
2. Required<T>: Todos os campos obrigatórios
O oposto de Partial. Útil quando você recebe um tipo com opcionais mas precisa garantir que tudo está preenchido:
interface Config {
apiUrl?: string;
timeout?: number;
retries?: number;
}
// Após validação, todos os campos são garantidos
type ValidatedConfig = Required<Config>;
// { apiUrl: string; timeout: number; retries: number; }
3. Pick<T, K>: Selecionar campos específicos
interface Post {
id: string;
title: string;
content: string;
author: string;
publishedAt: Date;
updatedAt: Date;
}
// Para listagem, só precisamos de alguns campos
type PostPreview = Pick<Post, "id" | "title" | "author" | "publishedAt">;
4. Omit<T, K>: Excluir campos específicos
// Para criar um post, não temos ainda o id e as datas
type CreatePostDTO = Omit<Post, "id" | "publishedAt" | "updatedAt">;
// { title: string; content: string; author: string; }
5. Record<K, V>: Objetos tipados
Substitui o infame { [key: string]: any } por algo muito mais seguro:
type CategorySlug = "performance" | "typescript" | "react" | "css";
const categoryColors: Record<CategorySlug, string> = {
performance: "from-amber-500 to-orange-600",
typescript: "from-blue-400 to-blue-600",
react: "from-indigo-500 to-violet-600",
css: "from-pink-500 to-purple-600",
};
// TypeScript vai reclamar se você esquecer alguma categoria
6. ReturnType<T>: Tipo do retorno de uma função
async function getUser(id: string) {
return { id, name: "Paulo", email: "paulo@email.com" };
}
// Em vez de duplicar a interface, extraia o tipo:
type UserResponse = Awaited<ReturnType<typeof getUser>>;
// { id: string; name: string; email: string; }
7. Awaited<T>: Desembrulhando Promises
type Posts = Awaited<ReturnType<typeof getAllPosts>>;
type SinglePost = Posts[number]; // tipo de um item do array
8. Parameters<T>: Tipos dos parâmetros de uma função
function createToast(message: string, type: "success" | "error", duration?: number) {}
type ToastArgs = Parameters<typeof createToast>;
// [message: string, type: "success" | "error", duration?: number]
9. NonNullable<T>: Removendo null e undefined
type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>; // string
// Útil em props de componentes
interface Props {
user?: User | null;
}
function useUser(props: Props) {
const user = props.user;
if (!user) return null;
// Aqui user é NonNullable<User>, TypeScript já sabe disso
}
10. Extract e Exclude: Filtrando Union Types
type Status = "pending" | "active" | "inactive" | "banned" | "deleted";
// Apenas os estados "positivos"
type ActiveStatus = Extract<Status, "pending" | "active">;
// "pending" | "active"
// Removendo estados indesejados
type SafeStatus = Exclude<Status, "banned" | "deleted">;
// "pending" | "active" | "inactive"
Conclusão
Utility Types não são recursos obscuros de TypeScript avançado; são ferramentas do dia a dia que tornam seu código mais expressivo e seguro. A próxima vez que você estiver criando uma interface nova, pergunte: "Posso derivar isso de algo que já existe?"
Gostou do conteúdo?
Se você precisar de ajuda aplicando essas técnicas no seu projeto, estou disponível para consultoria.

Autor
Paulo Reducino
Desenvolvedor Frontend com 5+ anos de experiência em React, Next.js e TypeScript. Especialista em performance, SEO e acessibilidade. Atualmente na Vizuh (Londres, UK).
