Menu

Utility types em TypeScript: a lista completa com exemplos

Todos os utility types embutidos do TypeScript em um só lugar: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ReturnType, Awaited, os tipos de string e outros, cada um com uma descrição de uma linha e um exemplo executável.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Utility types são tipos genéricos embutidos no TypeScript que transformam um tipo em outro. Em vez de escrever um segundo tipo User com todos os campos opcionais, você escreve Partial<User>; em vez de copiar três campos, Pick<User, "id" | "name">. Eles são globais, então não é preciso importar nada.

Quando User muda, os quatro tipos derivados acompanham. A biblioteca padrão do TypeScript (lib.es5.d.ts) declara 22 utility types. As seções abaixo listam todos eles, agrupados pelo tipo de tipo com que trabalham, com um link para a página detalhada quando ela existe.

Tipos de objeto: Partial, Required, Readonly, Pick, Omit, Record

Utility typeO que fazExemplo
Partial<T>torna toda propriedade opcionalPartial<User> para um payload de atualização
Required<T>torna toda propriedade obrigatória (remove o ?)Required<Config> depois de aplicar os padrões
Readonly<T>torna toda propriedade readonlyReadonly<State>
Pick<T, K>mantém só as chaves KPick<User, "id" | "name">
Omit<T, K>remove as chaves KOmit<User, "password">
Record<K, V>um tipo de objeto com chaves K e valores VRecord<"en" | "de", string>

Required<T> é o oposto de Partial<T>; a página de Partial cobre os dois, incluindo o undefined explícito que um spread como este deixa passar.

Union types: Exclude, Extract, NonNullable

Utility typeO que fazExemplo
Exclude<U, M>remove os membros da union atribuíveis a MExclude<"a" | "b" | "c", "a"> é "b" | "c"
Extract<U, M>mantém os membros da union atribuíveis a MExtract<string | number, number> é number
NonNullable<T>remove null e undefinedNonNullable<string | null> é string

Esses três trabalham com unions, não com objetos. Essa é a diferença principal em relação a Pick e Omit, que recebem um tipo de objeto e uma lista das chaves dele.

Tipos de função e de classe: Parameters, ReturnType e outros

Utility typeO que fazExemplo
ReturnType<F>o tipo de retorno de um tipo de funçãoReturnType<typeof createStore>
Parameters<F>os tipos dos parâmetros como uma tuplaParameters<typeof fetchPage>[0]
ConstructorParameters<C>os parâmetros do construtor de uma classe como uma tuplaConstructorParameters<typeof Point>
InstanceType<C>o tipo da instância que um construtor criaInstanceType<typeof Point>
ThisParameterType<F>o tipo do parâmetro this de uma funçãoThisParameterType<typeof greet>
OmitThisParameter<F>o tipo da função sem o parâmetro thiso tipo de greet.bind(obj)
ThisType<T>define o tipo de this dentro dos métodos de um object literalusado com noImplicitThis em APIs de builder
NoInfer<T>impede que um parâmetro de tipo seja inferido a partir desta posiçãofallback: NoInfer<C>

typeof createOrder é necessário porque esses utilities recebem um tipo, e createOrder é um valor. O mesmo vale para classes: typeof Point é o tipo do construtor, enquanto Point sozinho, como tipo, já significa o tipo da instância.

NoInfer controla de onde um generic tira o seu tipo:

Sem NoInfer, o TypeScript inferiria C a partir dos dois argumentos e o ampliaria para "red" | "green" | "blue", então o erro de digitação no fallback seria aceito.

Tipos de string: Uppercase, Lowercase, Capitalize, Uncapitalize

Utility typeO que fazExemplo
Uppercase<S>passa um string literal type para maiúsculasUppercase<"get"> é "GET"
Lowercase<S>passa para minúsculasLowercase<"GET"> é "get"
Capitalize<S>passa o primeiro caractere para maiúsculaCapitalize<"name"> é "Name"
Uncapitalize<S>passa o primeiro caractere para minúsculaUncapitalize<"Name"> é "name"

Esses quatro são embutidos no compilador em vez de escritos em TypeScript, e são mais úteis dentro de template literal types, como `on${Capitalize<E>}` para nomes de handlers de eventos.

Promises: Awaited

Utility typeO que fazExemplo
Awaited<T>o tipo que você obtém com await, desembrulhando promises aninhadasAwaited<Promise<Promise<number>>> é number

Awaited<ReturnType<typeof fn>> é o jeito padrão de dar nome ao tipo do resultado de uma função async sem declará-lo separadamente.

Combinando utility types

Utility types se aninham. Algumas combinações aparecem com frequência suficiente para valer a pena saber de cor:

Leia um utility type aninhado de dentro para fora: Readonly<Pick<Post, "id" | "title">> primeiro mantém duas propriedades e depois as torna somente leitura. As mesmas peças montam um helper PartialBy que torna opcionais só algumas chaves; a página de Partial mostra ele completo.

Utility types não fazem nada em tempo de execução

Todo utility type é apagado quando o código é compilado. Um valor com tipo Omit<User, "password"> ainda pode carregar uma senha em tempo de execução se o objeto de onde veio tinha uma:

O tipo só limita o que o seu código tem permissão para ler. Para remover um campo dos dados, tire-o com desestruturação como nas últimas linhas, e para impedir mutação em tempo de execução use Object.freeze, não Readonly. Os tipos embutidos são mapped types e conditional types de uma linha, então as mesmas ferramentas permitem escrever os seus.

Perguntas frequentes

O que são utility types no TypeScript?

Tipos genéricos que vêm com o TypeScript e transformam outros tipos: Partial<T> torna toda propriedade opcional, Pick<T, K> mantém algumas propriedades, ReturnType<F> pega o tipo de retorno de uma função, e assim por diante. Eles são declarados na biblioteca padrão, então você os usa sem importar nada.

Preciso importar os utility types?

Não. Partial, Omit, Record, ReturnType e os demais são tipos globais dos arquivos de biblioteca embutidos no TypeScript. Escreva Partial<User> em qualquer lugar; não precisa de import nem de pacote npm.

Quais utility types vêm embutidos no TypeScript?

22, todos declarados em lib.es5.d.ts: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ConstructorParameters, ReturnType, InstanceType, ThisParameterType, OmitThisParameter, ThisType, NoInfer, Awaited, Uppercase, Lowercase, Capitalize e Uncapitalize.

Utility types mudam objetos em tempo de execução?

Não. Eles só descrevem tipos e são apagados do JavaScript gerado. Omit<User, "password"> não apaga uma propriedade password, e Readonly<T> não congela nada. Para mudar o objeto de verdade, escreva o código: um padrão rest na desestruturação, Object.freeze, e assim por diante.

Posso escrever meus próprios utility types?

Sim. Os embutidos são TypeScript comum: a maioria é um mapped type ou um conditional type de uma linha em lib.es5.d.ts. type Nullable<T> = { [K in keyof T]: T[K] | null } é um utility type personalizado escrito do mesmo jeito.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR